├── core ├── pubkeyConverter │ ├── export_test.go │ └── errors.go ├── check │ ├── interface.go │ ├── ifHrp.go │ ├── ifNil.go │ ├── ifHrp_test.go │ ├── ifZero.go │ └── ifNil_test.go ├── trimmers.go ├── optionals.go ├── sync │ ├── interface.go │ ├── rwmutex_test.go │ └── rwmutex.go ├── sliceUtil │ ├── sliceUtil.go │ └── sliceUtil_test.go ├── closing │ ├── interface.go │ ├── safeChanCloser.go │ └── safeChanCloser_test.go ├── counting │ ├── interface.go │ ├── nullCounts_test.go │ ├── nullCounts.go │ ├── concurrentShardedCounts_test.go │ ├── concurrentShardedCountsWithSize_test.go │ └── concurrentShardedCounts.go ├── mock │ ├── connectedAddressesHandlerMock.go │ ├── intRandomizerStub.go │ ├── stableTagProviderStub.go │ ├── epochSubscriberHandlerStub.go │ ├── gasScheduleSubscribeHandlerStub.go │ ├── marshalizerStub.go │ ├── hasherStub.go │ ├── statusHandlerMock.go │ ├── hasherMock.go │ ├── alarmSchedulerStub.go │ ├── pathManagerStub.go │ ├── marshalizerMock.go │ ├── enableEpochsHandlerStub.go │ ├── loggerMock.go │ └── appStatusHandlerStub.go ├── libLocator │ ├── vmLocator_darwin.go │ ├── vmLocator_windows.go │ └── vmLocator_linux.go ├── watchdog │ ├── errors.go │ └── disabledWatchDog.go ├── accumulator │ └── export_test.go ├── atomic │ ├── int64.go │ ├── uint32.go │ ├── uint64.go │ ├── string.go │ ├── string_test.go │ ├── int64_test.go │ ├── uint32_test.go │ ├── uint64_test.go │ ├── flag.go │ ├── counter.go │ ├── flag_test.go │ └── counter_test.go ├── errors │ └── interface.go ├── sharding │ └── errors.go ├── machineID.go ├── machineID_test.go ├── keyValStorage │ ├── keyValStorage_test.go │ └── keyValStorage.go ├── appStatusPolling │ ├── errors.go │ └── appStatusPolling.go ├── random │ ├── fisherYates.go │ ├── concurrentSafeIntRandomizer.go │ ├── fisherYates_test.go │ └── concurrentSafeIntRandomizer_test.go ├── trimmers_test.go ├── peerID.go ├── peerID_test.go ├── loggingFunctions_test.go ├── epochFlags.go ├── keyLoader.go ├── queue │ ├── hashQueue.go │ └── hashQueue_test.go ├── loggingFunctions.go ├── nodetype │ ├── nodeTypeProvider.go │ └── nodeTypeProvider_test.go ├── common.go ├── partitioning │ └── dataSplit.go ├── export_test.go ├── errorHandling.go ├── throttler │ └── numGoRoutinesThrottler.go ├── getNodeFromDBErrWithKey.go ├── epochFlags_test.go ├── getNodeFromDBErrWithKey_test.go ├── versioning │ ├── txVersionChecker_test.go │ └── versionComparator.go └── container │ └── mutexMap.go ├── README.md ├── marshal ├── interface.go ├── testing.go ├── testSizeCheckUnmarshal │ ├── testStruct.proto │ └── testStructs_test.go ├── marshalizer.go ├── errors.go ├── factory │ ├── marshalizerFactory.go │ └── marshalizerFactory_test.go ├── txJsonMarshalizer_test.go ├── jsonMarshalizer.go ├── gogoProtoMarshalizer.go ├── txJsonMarshalizer.go ├── sizeCheckUnmarshalizer.go └── gogoProtoMarshalizer_test.go ├── data ├── guardians │ ├── guardians.go │ └── guardians.proto ├── validator │ ├── validatorStatistics.go │ └── validatorStatistics.proto ├── alteredAccount │ └── alteredAccount.go ├── api │ ├── blockInfo.go │ ├── apiESDTSupply.go │ ├── apiBlock_test.go │ ├── guardianData.go │ ├── options.go │ ├── apiAccountResponse.go │ └── apiHyperBlock.go ├── typeConverters │ ├── interface.go │ ├── errors.go │ └── uint64ByteSlice │ │ └── bigEndianConverter.go ├── outport │ ├── status.go │ ├── errors.go │ ├── config.proto │ ├── feeInfo.go │ ├── consts.go │ └── outportBlock.go ├── block │ ├── interface.go │ ├── headerProof.go │ ├── export_test.go │ ├── headerProof_test.go │ ├── peerBlock.go │ ├── emptyHeaderCreator.go │ ├── emptyMetablockCreator.go │ ├── emptyHeaderCreator_test.go │ ├── emptyHeaderV2Creator.go │ ├── emptyMetablockCreator_test.go │ ├── unmarshal.go │ ├── emptyHeaderV2Creator_test.go │ ├── headerProof.proto │ ├── metaBlockChecks_test.go │ ├── trigger.proto │ ├── emptyBlockCreatorsContainer.go │ ├── blockV2.proto │ └── epochStartHandler.go ├── consensusRewardData.go ├── types.go ├── common.go ├── esdt │ ├── esdt.go │ ├── proto │ │ └── esdt.proto │ └── common_test.go ├── endProcess │ ├── endProcessArgument_test.go │ └── endProcessArgument.go ├── mock │ ├── updaterStub.go │ ├── emptyBlockCreatorStub.go │ ├── hasherMock127.go │ ├── marshalizerStub.go │ ├── hasherStub.go │ ├── hasherMock.go │ ├── nonceHashConverterMock.go │ ├── keccakMock.go │ ├── protobufMock.go │ ├── marshalizerMock.go │ ├── pubkeyConverterStub.go │ └── appStatusHandlerStub.go ├── metrics │ ├── metrics.proto │ └── metrics.go ├── vm │ ├── returnDataKind.go │ ├── callType_test.go │ ├── callType.go │ └── vmOutputApi_test.go ├── batch │ ├── batch.proto │ └── batch.go ├── transaction │ ├── interface.go │ ├── log.go │ ├── status.go │ ├── apiTransactionResult_test.go │ ├── constants.go │ ├── errors.go │ ├── log_test.go │ ├── log.proto │ └── frontendTransaction.go ├── rewardTx │ ├── rewardTx.proto │ ├── rewardTx_test.go │ └── rewardTx.go ├── receipt │ ├── receipt.proto │ ├── receipt_test.go │ └── receipt.go ├── generatedCode.md ├── stateChange │ ├── accountChanges_test.go │ ├── accountChanges.go │ └── stateChange.proto ├── scheduled │ └── scheduled.proto ├── smartContractResult │ ├── smartContractResult.proto │ └── smartContractResult.go └── bigIntCaster.go ├── hashing ├── blake2b │ ├── errors.go │ └── blake2b_test.go ├── factory │ ├── errors.go │ ├── hasherFactory.go │ └── hasherFactory_test.go ├── hasher.go ├── fnv │ └── fnv.go ├── sha256 │ └── sha256.go └── keccak │ └── keccak.go ├── .gitignore ├── Makefile ├── .github └── workflows │ ├── pr-tests.yml │ └── golangci-lint.yml ├── display ├── placeholders.go ├── errors.go └── placeholders_test.go └── go.mod /core/pubkeyConverter/export_test.go: -------------------------------------------------------------------------------- 1 | package pubkeyConverter 2 | 3 | var Prefix = bech32Config.prefix 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mx-chain-core-go 2 | 3 | mx-chain-go common components and data that can be used in other repositories as well 4 | -------------------------------------------------------------------------------- /marshal/interface.go: -------------------------------------------------------------------------------- 1 | package marshal 2 | 3 | // Sizer contains method Size that is needed to get the size of a proto obj 4 | type Sizer interface { 5 | Size() (n int) 6 | } 7 | -------------------------------------------------------------------------------- /data/guardians/guardians.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=. guardians.proto 2 | package guardians 3 | -------------------------------------------------------------------------------- /core/check/interface.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | // NilInterfaceChecker checks if an interface's underlying object is nil 4 | type NilInterfaceChecker interface { 5 | IsInterfaceNil() bool 6 | } 7 | -------------------------------------------------------------------------------- /data/validator/validatorStatistics.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=. validatorStatistics.proto 2 | package validator 3 | -------------------------------------------------------------------------------- /data/alteredAccount/alteredAccount.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=$GOPATH/src alteredAccount.proto 2 | package alteredAccount 3 | -------------------------------------------------------------------------------- /hashing/blake2b/errors.go: -------------------------------------------------------------------------------- 1 | package blake2b 2 | 3 | import "errors" 4 | 5 | // ErrInvalidHashSize signals that an invalid hash size has been provided 6 | var ErrInvalidHashSize = errors.New("invalid hash size provided") 7 | -------------------------------------------------------------------------------- /hashing/factory/errors.go: -------------------------------------------------------------------------------- 1 | package factory 2 | 3 | import "errors" 4 | 5 | // ErrNoHasherInConfig signals that no hasher was provided in the config file 6 | var ErrNoHasherInConfig = errors.New("no hasher provided in config file") 7 | -------------------------------------------------------------------------------- /core/trimmers.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | // GetTrimmedPk returns a trimmed string to the pkPrefixSize value 4 | func GetTrimmedPk(pk string) string { 5 | if len(pk) > pkPrefixSize { 6 | pk = pk[:pkPrefixSize] 7 | } 8 | 9 | return pk 10 | } 11 | -------------------------------------------------------------------------------- /data/api/blockInfo.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | // BlockInfo is a data transfer object used on the API 4 | type BlockInfo struct { 5 | Nonce uint64 `json:"nonce,omitempty"` 6 | Hash string `json:"hash,omitempty"` 7 | RootHash string `json:"rootHash,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /data/typeConverters/interface.go: -------------------------------------------------------------------------------- 1 | package typeConverters 2 | 3 | // Uint64ByteSliceConverter converts byte slice to/from uint64 4 | type Uint64ByteSliceConverter interface { 5 | ToByteSlice(uint64) []byte 6 | ToUint64([]byte) (uint64, error) 7 | IsInterfaceNil() bool 8 | } 9 | -------------------------------------------------------------------------------- /data/outport/status.go: -------------------------------------------------------------------------------- 1 | package outport 2 | 3 | // StatusInfo holds the fields for the transaction status 4 | type StatusInfo struct { 5 | CompletedEvent bool `json:"completedEvent"` 6 | ErrorEvent bool `json:"errorEvent"` 7 | Status string `json:"status"` 8 | } 9 | -------------------------------------------------------------------------------- /data/block/interface.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import "github.com/multiversx/mx-chain-core-go/data" 4 | 5 | // EmptyBlockCreator is able to create empty block instances 6 | type EmptyBlockCreator interface { 7 | CreateNewHeader() data.HeaderHandler 8 | IsInterfaceNil() bool 9 | } 10 | -------------------------------------------------------------------------------- /hashing/hasher.go: -------------------------------------------------------------------------------- 1 | package hashing 2 | 3 | // BlsHashSize specifies the hash size for using bls scheme 4 | const BlsHashSize = 16 5 | 6 | // Hasher provides hashing services 7 | type Hasher interface { 8 | Compute(string) []byte 9 | Size() int 10 | IsInterfaceNil() bool 11 | } 12 | -------------------------------------------------------------------------------- /data/consensusRewardData.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | // ConsensusRewardData holds the required data for rewarding validators in a specific round and epoch 4 | type ConsensusRewardData struct { 5 | Round uint64 6 | Epoch uint32 7 | PubKeys []string 8 | Addresses []string 9 | } 10 | -------------------------------------------------------------------------------- /data/types.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | // LogData holds the data needed for indexing logs and events 4 | type LogData struct { 5 | LogHandler 6 | TxHash string 7 | } 8 | 9 | // KeyValuePair is a tuple of (key, value) 10 | type KeyValuePair struct { 11 | Key []byte 12 | Value []byte 13 | } 14 | -------------------------------------------------------------------------------- /core/optionals.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | // OptionalUint32 holds an optional uint32 value 4 | type OptionalUint32 struct { 5 | Value uint32 6 | HasValue bool 7 | } 8 | 9 | // OptionalUint64 holds an optional uint64 value 10 | type OptionalUint64 struct { 11 | Value uint64 12 | HasValue bool 13 | } 14 | -------------------------------------------------------------------------------- /core/sync/interface.go: -------------------------------------------------------------------------------- 1 | package sync 2 | 3 | // KeyRWMutexHandler is a mutex that can be used to lock/unlock a resource identified by a key 4 | type KeyRWMutexHandler interface { 5 | Lock(key string) 6 | Unlock(key string) 7 | RLock(key string) 8 | RUnlock(key string) 9 | IsInterfaceNil() bool 10 | } 11 | -------------------------------------------------------------------------------- /data/block/headerProof.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=. headerProof.proto 2 | package block 3 | 4 | // IsInterfaceNil returns true if there is no value under the interface 5 | func (x *HeaderProof) IsInterfaceNil() bool { 6 | return x == nil 7 | } 8 | -------------------------------------------------------------------------------- /core/sliceUtil/sliceUtil.go: -------------------------------------------------------------------------------- 1 | package sliceUtil 2 | 3 | // TrimSliceSliceByte creates a copy of the provided slice without the excess capacity 4 | func TrimSliceSliceByte(in [][]byte) [][]byte { 5 | if len(in) == 0 { 6 | return [][]byte{} 7 | } 8 | ret := make([][]byte, len(in)) 9 | copy(ret, in) 10 | return ret 11 | } 12 | -------------------------------------------------------------------------------- /core/closing/interface.go: -------------------------------------------------------------------------------- 1 | package closing 2 | 3 | // Closer closes all stuff released by an object 4 | type Closer interface { 5 | Close() error 6 | } 7 | 8 | // IntRandomizer interface provides functionality over generating integer numbers 9 | type IntRandomizer interface { 10 | Intn(n int) int 11 | IsInterfaceNil() bool 12 | } 13 | -------------------------------------------------------------------------------- /data/block/export_test.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | func (m *MiniBlockHeader) SetMiniBlockHeaderReserved(mbhr *MiniBlockHeaderReserved) error { 4 | return m.setMiniBlockHeaderReserved(mbhr) 5 | } 6 | 7 | func (m *MiniBlockHeader) GetMiniBlockHeaderReserved() (*MiniBlockHeaderReserved, error) { 8 | return m.getMiniBlockHeaderReserved() 9 | } 10 | -------------------------------------------------------------------------------- /data/common.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | // TrimHeaderHandlerSlice creates a copy of the provided slice without the excess capacity 4 | func TrimHeaderHandlerSlice(in []HeaderHandler) []HeaderHandler { 5 | if len(in) == 0 { 6 | return []HeaderHandler{} 7 | } 8 | ret := make([]HeaderHandler, len(in)) 9 | copy(ret, in) 10 | return ret 11 | } 12 | -------------------------------------------------------------------------------- /data/esdt/esdt.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=proto -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=. esdt.proto 2 | package esdt 3 | 4 | import "math/big" 5 | 6 | // New returns a new batch from given buffers 7 | func New() *ESDigitalToken { 8 | return &ESDigitalToken{ 9 | Value: big.NewInt(0), 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /core/counting/interface.go: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | // Counts is an interface to interact with counts 4 | type Counts interface { 5 | GetTotal() int64 6 | String() string 7 | IsInterfaceNil() bool 8 | } 9 | 10 | // CountsWithSize is an interface to interact with counts 11 | type CountsWithSize interface { 12 | Counts 13 | GetTotalSize() int64 14 | } 15 | -------------------------------------------------------------------------------- /core/mock/connectedAddressesHandlerMock.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // ConnectedAddressesMock represents a mock implementation of the ConnectedAddresses 4 | type ConnectedAddressesMock struct { 5 | } 6 | 7 | // ConnectedAddresses returns an empty slice of string 8 | func (cam *ConnectedAddressesMock) ConnectedAddresses() []string { 9 | return []string{} 10 | } 11 | -------------------------------------------------------------------------------- /core/check/ifHrp.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | // IfHrp tests if the provided string is human readable - does contain only alphabetic characters 4 | func IfHrp(s string) bool { 5 | if s == "" { 6 | return false 7 | } 8 | 9 | for _, r := range s { 10 | if (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') { 11 | return false 12 | } 13 | } 14 | return true 15 | } 16 | -------------------------------------------------------------------------------- /core/libLocator/vmLocator_darwin.go: -------------------------------------------------------------------------------- 1 | //go:build darwin 2 | // +build darwin 3 | 4 | package vm 5 | 6 | import ( 7 | "os/user" 8 | ) 9 | 10 | const libName = "libhera.dylib" 11 | 12 | func WASMLibLocation() string { 13 | usr, err := user.Current() 14 | if err != nil { 15 | return "" 16 | } 17 | return usr.HomeDir + "/multiversx-vm-binaries/" + libName 18 | } 19 | -------------------------------------------------------------------------------- /core/libLocator/vmLocator_windows.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | // +build windows 3 | 4 | package vm 5 | 6 | import ( 7 | "os/user" 8 | ) 9 | 10 | const libName = "libhera.dll" 11 | 12 | func WASMLibLocation() string { 13 | usr, err := user.Current() 14 | if err != nil { 15 | return "" 16 | } 17 | return usr.HomeDir + "\\multiversx-vm-binaries\\" + libName 18 | } 19 | -------------------------------------------------------------------------------- /data/block/headerProof_test.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func TestHeaderProof_IsInterfaceNil(t *testing.T) { 10 | t.Parallel() 11 | 12 | var proof *HeaderProof 13 | require.True(t, proof.IsInterfaceNil()) 14 | 15 | proof = &HeaderProof{} 16 | require.False(t, proof.IsInterfaceNil()) 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories 15 | /vendor 16 | 17 | # IDE files 18 | .idea/ 19 | 20 | # Go workspace file 21 | go.work 22 | 23 | .idea 24 | -------------------------------------------------------------------------------- /core/watchdog/errors.go: -------------------------------------------------------------------------------- 1 | package watchdog 2 | 3 | import "errors" 4 | 5 | // ErrNilAlarmScheduler is raised when a valid alarm scheduler is expected but nil is used 6 | var ErrNilAlarmScheduler = errors.New("nil alarm scheduler") 7 | 8 | // ErrNilEndProcessChan is raised when a valid end process chan is expected but nil is used 9 | var ErrNilEndProcessChan = errors.New("nil end process chan") 10 | -------------------------------------------------------------------------------- /data/api/apiESDTSupply.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | // ESDTSupply represents the structure for esdt supply that is returned by api routes 4 | type ESDTSupply struct { 5 | InitialMinted string `json:"initialMinted"` 6 | Supply string `json:"supply"` 7 | Burned string `json:"burned"` 8 | Minted string `json:"minted"` 9 | RecomputedSupply bool `json:"recomputedSupply"` 10 | } 11 | -------------------------------------------------------------------------------- /data/endProcess/endProcessArgument_test.go: -------------------------------------------------------------------------------- 1 | package endProcess 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func TestGetDummyEndProcessChannel(t *testing.T) { 10 | emptyChannel := GetDummyEndProcessChannel() 11 | require.Empty(t, emptyChannel) 12 | 13 | emptyChannel <- ArgEndProcess{ 14 | Reason: "reason", 15 | } 16 | require.NotEmpty(t, emptyChannel) 17 | } 18 | -------------------------------------------------------------------------------- /core/accumulator/export_test.go: -------------------------------------------------------------------------------- 1 | package accumulator 2 | 3 | import "time" 4 | 5 | const MinimumAllowedTime = minimumAllowedTime 6 | 7 | func (ta *timeAccumulator) Data() []interface{} { 8 | ta.mut.Lock() 9 | data := make([]interface{}, len(ta.data)) 10 | ta.mut.Unlock() 11 | 12 | return data 13 | } 14 | 15 | func (ta *timeAccumulator) ComputeWaitTime() time.Duration { 16 | return ta.computeWaitTime() 17 | } 18 | -------------------------------------------------------------------------------- /core/libLocator/vmLocator_linux.go: -------------------------------------------------------------------------------- 1 | //go:build linux 2 | // +build linux 3 | 4 | package vm 5 | 6 | import ( 7 | "os/user" 8 | ) 9 | 10 | const libName = "libhera.so" 11 | 12 | // WASMLibLocation defines the wasm library location 13 | func WASMLibLocation() string { 14 | usr, err := user.Current() 15 | if err != nil { 16 | return "" 17 | } 18 | return usr.HomeDir + "/multiversx-vm-binaries/" + libName 19 | } 20 | -------------------------------------------------------------------------------- /data/typeConverters/errors.go: -------------------------------------------------------------------------------- 1 | package typeConverters 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | // ErrNilByteSlice signals that a nil byte slice has been provided 8 | var ErrNilByteSlice = errors.New("nil byte slice") 9 | 10 | // ErrByteSliceLenShouldHaveBeen8 signals that the byte slice provided has a wrong length (should have been 8) 11 | var ErrByteSliceLenShouldHaveBeen8 = errors.New("byte slice's len should have been 8") 12 | -------------------------------------------------------------------------------- /core/atomic/int64.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import "sync/atomic" 4 | 5 | // Int64 is a wrapper for atomic operations on int64 6 | type Int64 struct { 7 | value int64 8 | } 9 | 10 | // Set sets the value 11 | func (variable *Int64) Set(value int64) { 12 | atomic.StoreInt64(&variable.value, value) 13 | } 14 | 15 | // Get gets the value 16 | func (variable *Int64) Get() int64 { 17 | return atomic.LoadInt64(&variable.value) 18 | } 19 | -------------------------------------------------------------------------------- /data/outport/errors.go: -------------------------------------------------------------------------------- 1 | package outport 2 | 3 | import "errors" 4 | 5 | var errInvalidHeaderType = errors.New("received invalid/unknown header type") 6 | 7 | var errNilBodyHandler = errors.New("nil body handler") 8 | 9 | var errCannotCastBlockBody = errors.New("cannot cast block body") 10 | 11 | var errNilHeaderProof = errors.New("nil header proof") 12 | 13 | var errCannotCastHeaderProof = errors.New("cannot cast header proof") 14 | -------------------------------------------------------------------------------- /marshal/testing.go: -------------------------------------------------------------------------------- 1 | package marshal 2 | 3 | // MarshalizersAvailableForTesting represents all marshalizers registered that will be used in tests. 4 | // In this manner we assure that any modification on a serializable DTO will always be checked against 5 | // all registered marshalizers 6 | var MarshalizersAvailableForTesting = map[string]Marshalizer{ 7 | "json": &JsonMarshalizer{}, 8 | "protobuf": &GogoProtoMarshalizer{}, 9 | } 10 | -------------------------------------------------------------------------------- /core/atomic/uint32.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import "sync/atomic" 4 | 5 | // Uint32 is a wrapper for atomic operations on uint32 6 | type Uint32 struct { 7 | value uint32 8 | } 9 | 10 | // Set sets the value 11 | func (variable *Uint32) Set(value uint32) { 12 | atomic.StoreUint32(&variable.value, value) 13 | } 14 | 15 | // Get gets the value 16 | func (variable *Uint32) Get() uint32 { 17 | return atomic.LoadUint32(&variable.value) 18 | } 19 | -------------------------------------------------------------------------------- /core/atomic/uint64.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import "sync/atomic" 4 | 5 | // Uint64 is a wrapper for atomic operations on uint64 6 | type Uint64 struct { 7 | value uint64 8 | } 9 | 10 | // Set sets the value 11 | func (variable *Uint64) Set(value uint64) { 12 | atomic.StoreUint64(&variable.value, value) 13 | } 14 | 15 | // Get gets the value 16 | func (variable *Uint64) Get() uint64 { 17 | return atomic.LoadUint64(&variable.value) 18 | } 19 | -------------------------------------------------------------------------------- /core/errors/interface.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | // WrappableError is an interface that extends error and represents a multi-layer error 4 | type WrappableError interface { 5 | error 6 | 7 | WrapWithMessage(errMessage string) WrappableError 8 | WrapWithStackTrace() WrappableError 9 | WrapWithError(err error) WrappableError 10 | GetBaseError() error 11 | GetLastError() error 12 | 13 | Unwrap() error 14 | Is(target error) bool 15 | } 16 | -------------------------------------------------------------------------------- /core/sharding/errors.go: -------------------------------------------------------------------------------- 1 | package sharding 2 | 3 | import "errors" 4 | 5 | // ErrInvalidNumberOfShards signals that an invalid number of shards was passed to the sharding registry 6 | var ErrInvalidNumberOfShards = errors.New("the number of shards must be greater than zero") 7 | 8 | // ErrInvalidShardId signals that an invalid shard is was passed 9 | var ErrInvalidShardId = errors.New("shard id must be smaller than the total number of shards") 10 | -------------------------------------------------------------------------------- /data/api/apiBlock_test.go: -------------------------------------------------------------------------------- 1 | package api_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/multiversx/mx-chain-core-go/data/api" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestAPIBlockFetchType(t *testing.T) { 11 | byNonceType := api.BlockFetchTypeByNonce 12 | require.Equal(t, "by-nonce", byNonceType.String()) 13 | 14 | byHashType := api.BlockFetchTypeByHash 15 | require.Equal(t, "by-hash", byHashType.String()) 16 | } 17 | -------------------------------------------------------------------------------- /data/guardians/guardians.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package protoBuiltInFunctions; 4 | 5 | option go_package = "guardians"; 6 | option (gogoproto.stable_marshaler_all) = true; 7 | 8 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 9 | 10 | message Guardian { 11 | bytes Address = 1; 12 | uint32 ActivationEpoch = 2; 13 | bytes ServiceUID = 3; 14 | } 15 | 16 | message Guardians { 17 | repeated Guardian Slice = 1; 18 | } 19 | -------------------------------------------------------------------------------- /data/mock/updaterStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // UpdaterStub - 4 | type UpdaterStub struct { 5 | UpdateCalled func(key, value []byte) error 6 | } 7 | 8 | // Update - 9 | func (updater *UpdaterStub) Update(key, value []byte) error { 10 | return updater.UpdateCalled(key, value) 11 | } 12 | 13 | // IsInterfaceNil returns true if there is no value under the interface 14 | func (updater *UpdaterStub) IsInterfaceNil() bool { 15 | return updater == nil 16 | } 17 | -------------------------------------------------------------------------------- /marshal/testSizeCheckUnmarshal/testStruct.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package testSizeCheckUnmarshal; 4 | 5 | option (gogoproto.stable_marshaler_all) = true; 6 | 7 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 8 | 9 | message TestStruct1 { 10 | uint64 field1 = 1; 11 | bytes field2 = 2; 12 | } 13 | 14 | message TestStruct2 { 15 | uint64 field1 = 1; 16 | bytes field2 = 2; 17 | bytes field3 = 3; 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /data/endProcess/endProcessArgument.go: -------------------------------------------------------------------------------- 1 | package endProcess 2 | 3 | // ArgEndProcess represents an object that encapsulates the reason and description for ending the process 4 | type ArgEndProcess struct { 5 | Reason string 6 | Description string 7 | } 8 | 9 | // GetDummyEndProcessChannel returns a dummy channel of type ArgEndProcess 10 | func GetDummyEndProcessChannel() chan ArgEndProcess { 11 | ch := make(chan ArgEndProcess, 1) 12 | 13 | return ch 14 | } 15 | -------------------------------------------------------------------------------- /data/outport/config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package proto; 4 | 5 | option go_package = "github.com/multiversx/mx-chain-core-go/data/outport;outport"; 6 | option (gogoproto.stable_marshaler_all) = true; 7 | 8 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 9 | 10 | message OutportConfig { 11 | uint32 ShardID = 1 [(gogoproto.jsontag) = "shardID"]; 12 | bool IsInImportDBMode = 2 [(gogoproto.jsontag) = "isInImportDBMode"]; 13 | } 14 | -------------------------------------------------------------------------------- /data/metrics/metrics.proto: -------------------------------------------------------------------------------- 1 | 2 | syntax = "proto3"; 3 | 4 | package metrics; 5 | 6 | option go_package = "metrics"; 7 | option (gogoproto.stable_marshaler_all) = true; 8 | 9 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 10 | 11 | 12 | message Metric { 13 | string Key = 1; 14 | oneof Value { 15 | uint64 ValUint64 = 2; 16 | string ValString = 3; 17 | } 18 | } 19 | 20 | message MetricsList { 21 | repeated Metric Metrics = 1 [(gogoproto.nullable) = false]; 22 | } 23 | -------------------------------------------------------------------------------- /core/machineID.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import "github.com/denisbrodbeck/machineid" 4 | 5 | // GetAnonymizedMachineID returns the machine ID anonymized with the provided app ID string 6 | func GetAnonymizedMachineID(appID string) string { 7 | machineID, err := machineid.ProtectedID(appID) 8 | if err != nil { 9 | machineID = "unknown machine ID" 10 | } 11 | if len(machineID) > MaxMachineIDLen { 12 | machineID = machineID[:MaxMachineIDLen] 13 | } 14 | 15 | return machineID 16 | } 17 | -------------------------------------------------------------------------------- /core/mock/intRandomizerStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // IntRandomizerStub - 4 | type IntRandomizerStub struct { 5 | IntnCalled func(n int) int 6 | } 7 | 8 | // Intn - 9 | func (irs *IntRandomizerStub) Intn(n int) int { 10 | if irs.IntnCalled != nil { 11 | return irs.IntnCalled(n) 12 | } 13 | 14 | return 0 15 | } 16 | 17 | // IsInterfaceNil returns true if there is no value under the interface 18 | func (irs *IntRandomizerStub) IsInterfaceNil() bool { 19 | return irs == nil 20 | } 21 | -------------------------------------------------------------------------------- /core/machineID_test.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestGetAnonymizedMachineID(t *testing.T) { 10 | t.Parallel() 11 | 12 | firstVariant := GetAnonymizedMachineID("first") 13 | secondVariant := GetAnonymizedMachineID("second") 14 | 15 | assert.NotEqual(t, firstVariant, secondVariant) 16 | assert.Equal(t, MaxMachineIDLen, len(firstVariant)) 17 | assert.Equal(t, MaxMachineIDLen, len(secondVariant)) 18 | } 19 | -------------------------------------------------------------------------------- /data/vm/returnDataKind.go: -------------------------------------------------------------------------------- 1 | package vm 2 | 3 | // ReturnDataKind specifies how to interpret VMOutputs's return data. 4 | // More specifically, how to interpret returned data's first item. 5 | type ReturnDataKind int 6 | 7 | const ( 8 | // AsBigInt to interpret as big int 9 | AsBigInt ReturnDataKind = 1 << iota 10 | // AsBigIntString to interpret as big int string 11 | AsBigIntString 12 | // AsString to interpret as string 13 | AsString 14 | // AsHex to interpret as hex 15 | AsHex 16 | ) 17 | -------------------------------------------------------------------------------- /core/atomic/string.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import "sync/atomic" 4 | 5 | // String is a wrapper for atomic operations on String 6 | type String struct { 7 | value atomic.Value 8 | } 9 | 10 | // Set sets the value 11 | func (variable *String) Set(value string) { 12 | variable.value.Store(value) 13 | } 14 | 15 | // Get gets the value 16 | func (variable *String) Get() string { 17 | value := variable.value.Load() 18 | if value == nil { 19 | return "" 20 | } 21 | 22 | return value.(string) 23 | } 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | test: 2 | @echo " > Running unit tests" 3 | go test -cover -race -coverprofile=coverage.txt -covermode=atomic -v ./... 4 | 5 | lint-install: 6 | ifeq (,$(wildcard test -f bin/golangci-lint)) 7 | @echo "Installing golint" 8 | curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s 9 | endif 10 | 11 | run-lint: 12 | @echo "Running golint" 13 | bin/golangci-lint run --max-issues-per-linter 0 --max-same-issues 0 --timeout=2m 14 | 15 | lint: lint-install run-lint 16 | -------------------------------------------------------------------------------- /core/mock/stableTagProviderStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // StableTagProviderStub -- 4 | type StableTagProviderStub struct { 5 | FetchTagVersionCalled func() (string, error) 6 | } 7 | 8 | // FetchTagVersion -- 9 | func (s *StableTagProviderStub) FetchTagVersion() (string, error) { 10 | if s.FetchTagVersionCalled != nil { 11 | return s.FetchTagVersionCalled() 12 | } 13 | 14 | return "dummy", nil 15 | } 16 | 17 | // IsInterfaceNil -- 18 | func (s *StableTagProviderStub) IsInterfaceNil() bool { 19 | return s == nil 20 | } 21 | -------------------------------------------------------------------------------- /core/atomic/string_test.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestString_SetGet(t *testing.T) { 11 | var str String 12 | var wg sync.WaitGroup 13 | 14 | wg.Add(2) 15 | 16 | go func() { 17 | str.Set(str.Get() + "foo") 18 | wg.Done() 19 | }() 20 | 21 | go func() { 22 | str.Set(str.Get() + "bar") 23 | wg.Done() 24 | }() 25 | 26 | wg.Wait() 27 | require.Contains(t, []string{"foobar", "barfoo", "foo", "bar"}, str.Get()) 28 | } 29 | -------------------------------------------------------------------------------- /core/keyValStorage/keyValStorage_test.go: -------------------------------------------------------------------------------- 1 | package keyValStorage_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/multiversx/mx-chain-core-go/core/keyValStorage" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestNewKeyValStorage_GetKeyAndVal(t *testing.T) { 11 | t.Parallel() 12 | 13 | key := []byte("key") 14 | value := []byte("value") 15 | 16 | keyVal := keyValStorage.NewKeyValStorage(key, value) 17 | assert.NotNil(t, keyVal) 18 | assert.Equal(t, key, keyVal.Key()) 19 | assert.Equal(t, value, keyVal.Value()) 20 | } 21 | -------------------------------------------------------------------------------- /core/appStatusPolling/errors.go: -------------------------------------------------------------------------------- 1 | package appStatusPolling 2 | 3 | import "errors" 4 | 5 | // ErrNilAppStatusHandler will be returned when the AppStatusHandler is nil 6 | var ErrNilAppStatusHandler = errors.New("appStatusHandler is nil") 7 | 8 | // ErrPollingDurationToSmall will be returned when the polling duration is to small 9 | var ErrPollingDurationToSmall = errors.New("polling duration it's to small") 10 | 11 | // ErrNilHandlerFunc will be returned when the handler function is nil 12 | var ErrNilHandlerFunc = errors.New("handler function is nil") 13 | -------------------------------------------------------------------------------- /core/random/fisherYates.go: -------------------------------------------------------------------------------- 1 | package random 2 | 3 | type intRandomizer interface { 4 | Intn(n int) int 5 | } 6 | 7 | // FisherYatesShuffle will shuffle the provided indexes slice based on a provided randomizer 8 | func FisherYatesShuffle(indexes []int, randomizer intRandomizer) []int { 9 | newIndexes := make([]int, len(indexes)) 10 | copy(newIndexes, indexes) 11 | 12 | for i := len(newIndexes) - 1; i > 0; i-- { 13 | j := randomizer.Intn(i + 1) 14 | newIndexes[i], newIndexes[j] = newIndexes[j], newIndexes[i] 15 | } 16 | 17 | return newIndexes 18 | } 19 | -------------------------------------------------------------------------------- /core/mock/epochSubscriberHandlerStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // EpochSubscriberHandlerStub - 4 | type EpochSubscriberHandlerStub struct { 5 | EpochConfirmedCalled func(epoch uint32, timestamp uint64) 6 | } 7 | 8 | // EpochConfirmed - 9 | func (eshs *EpochSubscriberHandlerStub) EpochConfirmed(epoch uint32, timestamp uint64) { 10 | if eshs.EpochConfirmedCalled != nil { 11 | eshs.EpochConfirmedCalled(epoch, timestamp) 12 | } 13 | } 14 | 15 | // IsInterfaceNil - 16 | func (eshs *EpochSubscriberHandlerStub) IsInterfaceNil() bool { 17 | return eshs == nil 18 | } 19 | -------------------------------------------------------------------------------- /core/trimmers_test.go: -------------------------------------------------------------------------------- 1 | package core_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/multiversx/mx-chain-core-go/core" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestSubroundStartRound_GetPkToDisplayShouldTrim(t *testing.T) { 11 | pk := "1234567891234" 12 | pkToDisplay := core.GetTrimmedPk(pk) 13 | assert.Equal(t, "123456789123", pkToDisplay) 14 | } 15 | 16 | func TestSubroundStartRound_GetPkToDisplayShouldNotTrim(t *testing.T) { 17 | pk := "123456789123" 18 | pkToDisplay := core.GetTrimmedPk(pk) 19 | assert.Equal(t, pk, pkToDisplay) 20 | } 21 | -------------------------------------------------------------------------------- /data/mock/emptyBlockCreatorStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import "github.com/multiversx/mx-chain-core-go/data" 4 | 5 | // EmptyBlockCreatorStub - 6 | type EmptyBlockCreatorStub struct { 7 | CreateNewHeaderCalled func() data.HeaderHandler 8 | } 9 | 10 | // CreateNewHeader - 11 | func (e *EmptyBlockCreatorStub) CreateNewHeader() data.HeaderHandler { 12 | if e.CreateNewHeaderCalled != nil { 13 | return e.CreateNewHeaderCalled() 14 | } 15 | return nil 16 | } 17 | 18 | // IsInterfaceNil - 19 | func (e *EmptyBlockCreatorStub) IsInterfaceNil() bool { 20 | return e == nil 21 | } 22 | -------------------------------------------------------------------------------- /data/block/peerBlock.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import "github.com/multiversx/mx-chain-core-go/data" 4 | 5 | // SetPubKey - setter for public key 6 | func (pc *PeerChange) SetPubKey(pubKey []byte) error { 7 | if pc == nil { 8 | return data.ErrNilPointerReceiver 9 | } 10 | 11 | pc.PubKey = pubKey 12 | 13 | return nil 14 | } 15 | 16 | // SetShardIdDest - setter for destination shardID 17 | func (pc *PeerChange) SetShardIdDest(shardID uint32) error { 18 | if pc == nil { 19 | return data.ErrNilPointerReceiver 20 | } 21 | 22 | pc.ShardIdDest = shardID 23 | 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /core/mock/gasScheduleSubscribeHandlerStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // GasScheduleSubscribeHandlerStub - 4 | type GasScheduleSubscribeHandlerStub struct { 5 | GasScheduleChangeCalled func(gasSchedule map[string]map[string]uint64) 6 | } 7 | 8 | // GasScheduleChange - 9 | func (g *GasScheduleSubscribeHandlerStub) GasScheduleChange(gasSchedule map[string]map[string]uint64) { 10 | if g.GasScheduleChangeCalled != nil { 11 | g.GasScheduleChangeCalled(gasSchedule) 12 | } 13 | } 14 | 15 | // IsInterfaceNil - 16 | func (g *GasScheduleSubscribeHandlerStub) IsInterfaceNil() bool { 17 | return g == nil 18 | } 19 | -------------------------------------------------------------------------------- /data/batch/batch.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package proto; 4 | 5 | option go_package = "batch"; 6 | option (gogoproto.stable_marshaler_all) = true; 7 | 8 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 9 | 10 | // Transaction holds all the data needed for a value transfer or SC call 11 | message Batch { 12 | repeated bytes Data = 1 [(gogoproto.jsontag) = "data"]; 13 | bytes Reference = 2 [(gogoproto.jsontag) = "reference"]; 14 | uint32 ChunkIndex = 3 [(gogoproto.jsontag) = "chunkIndex"]; 15 | uint32 MaxChunks = 4 [(gogoproto.jsontag) = "maxChunks"]; 16 | } 17 | -------------------------------------------------------------------------------- /core/peerID.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import "github.com/mr-tron/base58/base58" 4 | 5 | // PeerID is a p2p peer identity. 6 | type PeerID string 7 | 8 | // NewPeerID creates a new peer id or returns an error 9 | func NewPeerID(input string) (PeerID, error) { 10 | pidBytes, err := base58.Decode(input) 11 | return PeerID(pidBytes), err 12 | } 13 | 14 | // Bytes returns the peer ID as byte slice 15 | func (pid PeerID) Bytes() []byte { 16 | return []byte(pid) 17 | } 18 | 19 | // Pretty returns a b58-encoded string of the peer id 20 | func (pid PeerID) Pretty() string { 21 | return base58.Encode(pid.Bytes()) 22 | } 23 | -------------------------------------------------------------------------------- /data/api/guardianData.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | // Guardian holds the relevant information for an account guardian 4 | type Guardian struct { 5 | Address string `json:"address"` 6 | ActivationEpoch uint32 `json:"activationEpoch"` 7 | ServiceUID string `json:"serviceUID"` 8 | } 9 | 10 | // GuardianData holds data relating to the configured guardian(s) and guarded state of an account 11 | type GuardianData struct { 12 | ActiveGuardian *Guardian `json:"activeGuardian,omitempty"` 13 | PendingGuardian *Guardian `json:"pendingGuardian,omitempty"` 14 | Guarded bool `json:"guarded"` 15 | } 16 | -------------------------------------------------------------------------------- /data/api/options.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import "github.com/multiversx/mx-chain-core-go/core" 4 | 5 | // AccountQueryOptions holds options for account queries 6 | type AccountQueryOptions struct { 7 | OnFinalBlock bool 8 | OnStartOfEpoch core.OptionalUint32 9 | BlockNonce core.OptionalUint64 10 | BlockHash []byte 11 | BlockRootHash []byte 12 | HintEpoch core.OptionalUint32 13 | WithKeys bool 14 | } 15 | 16 | // BlockQueryOptions holds options for block queries 17 | type BlockQueryOptions struct { 18 | WithTransactions bool 19 | WithLogs bool 20 | ForHyperblock bool 21 | } 22 | -------------------------------------------------------------------------------- /core/atomic/int64_test.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestInt64_SetGet(t *testing.T) { 12 | defer func() { 13 | r := recover() 14 | if r != nil { 15 | assert.Fail(t, fmt.Sprintf("should not have panicked %v", r)) 16 | } 17 | }() 18 | 19 | var number Int64 20 | var wg sync.WaitGroup 21 | 22 | wg.Add(2) 23 | 24 | go func() { 25 | number.Set(number.Get() - 42) 26 | wg.Done() 27 | }() 28 | 29 | go func() { 30 | number.Set(number.Get() + 43) 31 | wg.Done() 32 | }() 33 | 34 | wg.Wait() 35 | } 36 | -------------------------------------------------------------------------------- /core/atomic/uint32_test.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestUint32_SetGet(t *testing.T) { 12 | defer func() { 13 | r := recover() 14 | if r != nil { 15 | assert.Fail(t, fmt.Sprintf("should not have panicked %v", r)) 16 | } 17 | }() 18 | 19 | var number Uint32 20 | var wg sync.WaitGroup 21 | 22 | wg.Add(2) 23 | 24 | go func() { 25 | number.Set(number.Get() + 42) 26 | wg.Done() 27 | }() 28 | 29 | go func() { 30 | number.Set(number.Get() + 43) 31 | wg.Done() 32 | }() 33 | 34 | wg.Wait() 35 | } 36 | -------------------------------------------------------------------------------- /core/atomic/uint64_test.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestUint64_SetGet(t *testing.T) { 12 | defer func() { 13 | r := recover() 14 | if r != nil { 15 | assert.Fail(t, fmt.Sprintf("should not have panicked %v", r)) 16 | } 17 | }() 18 | 19 | var number Uint64 20 | var wg sync.WaitGroup 21 | 22 | wg.Add(2) 23 | 24 | go func() { 25 | number.Set(number.Get() + 42) 26 | wg.Done() 27 | }() 28 | 29 | go func() { 30 | number.Set(number.Get() + 43) 31 | wg.Done() 32 | }() 33 | 34 | wg.Wait() 35 | } 36 | -------------------------------------------------------------------------------- /core/check/ifNil.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | // IfNil tests if the provided interface pointer or underlying object is nil 8 | func IfNil(checker NilInterfaceChecker) bool { 9 | if checker == nil { 10 | return true 11 | } 12 | return checker.IsInterfaceNil() 13 | } 14 | 15 | // IfNilReflect tests if the provided interface pointer or underlying pointer receiver is nil 16 | func IfNilReflect(i interface{}) bool { 17 | if v := reflect.ValueOf(i); v.IsValid() { 18 | if v.Kind() == reflect.Ptr && v.IsNil() { 19 | return true 20 | } 21 | return false 22 | } 23 | return true 24 | } 25 | -------------------------------------------------------------------------------- /core/counting/nullCounts_test.go: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func TestNullCounts(t *testing.T) { 10 | counts := NullCounts{} 11 | 12 | total := counts.GetTotal() 13 | asString := counts.String() 14 | 15 | require.Equal(t, int64(-1), total) 16 | require.Equal(t, asString, "counts not applicable") 17 | } 18 | 19 | func TestNullCounts_IsInterfaceNil(t *testing.T) { 20 | counts := &NullCounts{} 21 | require.False(t, counts.IsInterfaceNil()) 22 | 23 | thisIsNil := (*NullCounts)(nil) 24 | require.True(t, thisIsNil.IsInterfaceNil()) 25 | } 26 | -------------------------------------------------------------------------------- /data/batch/batch.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=. batch.proto 2 | package batch 3 | 4 | // New returns a new batch from given buffers 5 | func New(buffs ...[]byte) *Batch { 6 | return &Batch{ 7 | Data: buffs, 8 | } 9 | } 10 | 11 | // NewChunk returns a new batch containing a chunk from given buffers 12 | func NewChunk(chunkIndex uint32, reference []byte, maxChunks uint32, buffs ...[]byte) *Batch { 13 | return &Batch{ 14 | Data: buffs, 15 | Reference: reference, 16 | ChunkIndex: chunkIndex, 17 | MaxChunks: maxChunks, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /data/transaction/interface.go: -------------------------------------------------------------------------------- 1 | package transaction 2 | 3 | import "github.com/multiversx/mx-chain-core-go/data/block" 4 | 5 | // StatusComputerHandler computes a transaction status 6 | type StatusComputerHandler interface { 7 | ComputeStatusWhenInStorageKnowingMiniblock(miniblockType block.Type, tx *ApiTransactionResult) (TxStatus, error) 8 | ComputeStatusWhenInStorageNotKnowingMiniblock(destinationShard uint32, tx *ApiTransactionResult) (TxStatus, error) 9 | SetStatusIfIsRewardReverted( 10 | tx *ApiTransactionResult, 11 | miniblockType block.Type, 12 | headerNonce uint64, 13 | headerHash []byte, 14 | ) (bool, error) 15 | } 16 | -------------------------------------------------------------------------------- /marshal/marshalizer.go: -------------------------------------------------------------------------------- 1 | package marshal 2 | 3 | import ( 4 | gproto "github.com/gogo/protobuf/proto" 5 | proto "github.com/golang/protobuf/proto" //nolint TODO:deprecated 6 | ) 7 | 8 | // GogoProtoObj groups the necessary of a gogo protobuf marshalizeble object 9 | type GogoProtoObj interface { 10 | gproto.Marshaler 11 | gproto.Unmarshaler 12 | proto.Message 13 | } 14 | 15 | // Marshalizer defines the 2 basic operations: serialize (marshal) and deserialize (unmarshal) 16 | type Marshalizer interface { 17 | Marshal(obj interface{}) ([]byte, error) 18 | Unmarshal(obj interface{}, buff []byte) error 19 | IsInterfaceNil() bool 20 | } 21 | -------------------------------------------------------------------------------- /core/keyValStorage/keyValStorage.go: -------------------------------------------------------------------------------- 1 | package keyValStorage 2 | 3 | // KeyValStorage holds a key and an associated value 4 | type keyValStorage struct { 5 | key []byte 6 | value []byte 7 | } 8 | 9 | // NewKeyValStorage creates a new key-value storage 10 | func NewKeyValStorage(key []byte, val []byte) *keyValStorage { 11 | return &keyValStorage{ 12 | key: key, 13 | value: val, 14 | } 15 | } 16 | 17 | // Key returns the key in the key-value storage 18 | func (k *keyValStorage) Key() []byte { 19 | return k.key 20 | } 21 | 22 | // Value returns the value in the key-value storage 23 | func (k *keyValStorage) Value() []byte { 24 | return k.value 25 | } 26 | -------------------------------------------------------------------------------- /.github/workflows/pr-tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | pull_request: 5 | branches: [ main, rc/*, feat/* ] 6 | types: [ opened, ready_for_review ] 7 | push: 8 | workflow_dispatch: 9 | 10 | jobs: 11 | test: 12 | name: Unit 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Set up Go 1.23.6 16 | uses: actions/setup-go@v5 17 | with: 18 | go-version: 1.23.6 19 | id: go 20 | 21 | - name: Check out code 22 | uses: actions/checkout@v4 23 | 24 | - name: Get dependencies 25 | run: | 26 | go get -v -t -d ./... 27 | - name: Unit tests 28 | run: make test 29 | -------------------------------------------------------------------------------- /data/block/emptyHeaderCreator.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import "github.com/multiversx/mx-chain-core-go/data" 4 | 5 | type emptyHeaderCreator struct{} 6 | 7 | // NewEmptyHeaderCreator is able to create empty header v1 instances 8 | func NewEmptyHeaderCreator() *emptyHeaderCreator { 9 | return &emptyHeaderCreator{} 10 | } 11 | 12 | // CreateNewHeader creates a new empty header v1 13 | func (creator *emptyHeaderCreator) CreateNewHeader() data.HeaderHandler { 14 | return &Header{} 15 | } 16 | 17 | // IsInterfaceNil returns true if there is no value under the interface 18 | func (creator *emptyHeaderCreator) IsInterfaceNil() bool { 19 | return creator == nil 20 | } 21 | -------------------------------------------------------------------------------- /data/mock/hasherMock127.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // HasherMock127 - 4 | type HasherMock127 struct { 5 | } 6 | 7 | // Compute - 8 | func (HasherMock127) Compute(s string) []byte { 9 | buff := make([]byte, 0) 10 | 11 | var i byte 12 | for i = 0; i < 127; i++ { 13 | buff = append(buff, i) 14 | } 15 | 16 | return buff 17 | } 18 | 19 | // EmptyHash - 20 | func (HasherMock127) EmptyHash() []byte { 21 | return nil 22 | } 23 | 24 | // Size - 25 | func (HasherMock127) Size() int { 26 | return 64 27 | } 28 | 29 | // IsInterfaceNil returns true if there is no value under the interface 30 | func (hash *HasherMock127) IsInterfaceNil() bool { 31 | return hash == nil 32 | } 33 | -------------------------------------------------------------------------------- /data/mock/marshalizerStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // MarshalizerStub - 4 | type MarshalizerStub struct { 5 | MarshalCalled func(obj interface{}) ([]byte, error) 6 | UnmarshalCalled func(obj interface{}, buff []byte) error 7 | } 8 | 9 | // Marshal - 10 | func (ms *MarshalizerStub) Marshal(obj interface{}) ([]byte, error) { 11 | return ms.MarshalCalled(obj) 12 | } 13 | 14 | // Unmarshal - 15 | func (ms *MarshalizerStub) Unmarshal(obj interface{}, buff []byte) error { 16 | return ms.UnmarshalCalled(obj, buff) 17 | } 18 | 19 | // IsInterfaceNil returns true if there is no value under the interface 20 | func (ms *MarshalizerStub) IsInterfaceNil() bool { 21 | return ms == nil 22 | } 23 | -------------------------------------------------------------------------------- /data/block/emptyMetablockCreator.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import "github.com/multiversx/mx-chain-core-go/data" 4 | 5 | type emptyMetaBlockCreator struct{} 6 | 7 | // NewEmptyMetaBlockCreator is able to create empty metablock instances 8 | func NewEmptyMetaBlockCreator() *emptyMetaBlockCreator { 9 | return &emptyMetaBlockCreator{} 10 | } 11 | 12 | // CreateNewHeader creates a new empty metablock 13 | func (creator *emptyMetaBlockCreator) CreateNewHeader() data.HeaderHandler { 14 | return &MetaBlock{} 15 | } 16 | 17 | // IsInterfaceNil returns true if there is no value under the interface 18 | func (creator *emptyMetaBlockCreator) IsInterfaceNil() bool { 19 | return creator == nil 20 | } 21 | -------------------------------------------------------------------------------- /core/counting/nullCounts.go: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | var _ Counts = (*NullCounts)(nil) 4 | 5 | // NullCounts implements null object pattern for counts 6 | type NullCounts struct { 7 | } 8 | 9 | // GetTotal returns -1 10 | func (counts *NullCounts) GetTotal() int64 { 11 | return -1 12 | } 13 | 14 | // GetTotalSize returns -1 15 | func (counts *NullCounts) GetTotalSize() int64 { 16 | return -1 17 | } 18 | 19 | // String returns a placeholder 20 | func (counts *NullCounts) String() string { 21 | return "counts not applicable" 22 | } 23 | 24 | // IsInterfaceNil returns true if there is no value under the interface 25 | func (counts *NullCounts) IsInterfaceNil() bool { 26 | return counts == nil 27 | } 28 | -------------------------------------------------------------------------------- /data/rewardTx/rewardTx.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package proto; 4 | 5 | option go_package = "github.com/multiversx/mx-chain-core-go/data/rewardTx;rewardTx"; 6 | option (gogoproto.stable_marshaler_all) = true; 7 | 8 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 9 | 10 | // RewardTx holds the data for a reward transaction 11 | message RewardTx { 12 | uint64 Round = 1 [(gogoproto.jsontag) = "round"]; 13 | bytes Value = 3 [(gogoproto.jsontag) = "value", (gogoproto.casttypewith) = "math/big.Int;github.com/multiversx/mx-chain-core-go/data.BigIntCaster"]; 14 | bytes RcvAddr = 4 [(gogoproto.jsontag) = "receiver"]; 15 | uint32 Epoch = 2 [(gogoproto.jsontag) = "epoch"]; 16 | } 17 | -------------------------------------------------------------------------------- /core/peerID_test.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestNewPeerID(t *testing.T) { 11 | t.Parallel() 12 | t.Run("invalid string should error", func(t *testing.T) { 13 | t.Parallel() 14 | 15 | providedStr := "provided str" 16 | _, err := NewPeerID(providedStr) 17 | assert.NotNil(t, err) 18 | }) 19 | t.Run("should work", func(t *testing.T) { 20 | t.Parallel() 21 | 22 | providedStr := "provided str" 23 | providedPeerID := PeerID(providedStr) 24 | pid, err := NewPeerID(providedPeerID.Pretty()) 25 | assert.Nil(t, err) 26 | assert.True(t, bytes.Equal([]byte(providedPeerID), pid.Bytes())) 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /data/block/emptyHeaderCreator_test.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/multiversx/mx-chain-core-go/core/check" 8 | "github.com/stretchr/testify/assert" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestNewEmptyHeaderCreator(t *testing.T) { 13 | t.Parallel() 14 | 15 | creator := NewEmptyHeaderCreator() 16 | require.False(t, check.IfNil(creator)) 17 | } 18 | 19 | func TestEmptyHeaderCreator_CreateNewHeader(t *testing.T) { 20 | t.Parallel() 21 | 22 | creator := NewEmptyHeaderCreator() 23 | header := creator.CreateNewHeader() 24 | require.False(t, check.IfNil(header)) 25 | assert.Equal(t, "*block.Header", fmt.Sprintf("%T", header)) 26 | } 27 | -------------------------------------------------------------------------------- /hashing/factory/hasherFactory.go: -------------------------------------------------------------------------------- 1 | package factory 2 | 3 | import ( 4 | "github.com/multiversx/mx-chain-core-go/hashing" 5 | "github.com/multiversx/mx-chain-core-go/hashing/blake2b" 6 | "github.com/multiversx/mx-chain-core-go/hashing/keccak" 7 | "github.com/multiversx/mx-chain-core-go/hashing/sha256" 8 | ) 9 | 10 | // NewHasher will return a new instance of hasher based on the value stored in config 11 | func NewHasher(name string) (hashing.Hasher, error) { 12 | switch name { 13 | case "sha256": 14 | return sha256.NewSha256(), nil 15 | case "keccak": 16 | return keccak.NewKeccak(), nil 17 | case "blake2b": 18 | return blake2b.NewBlake2b(), nil 19 | } 20 | 21 | return nil, ErrNoHasherInConfig 22 | } 23 | -------------------------------------------------------------------------------- /data/block/emptyHeaderV2Creator.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import "github.com/multiversx/mx-chain-core-go/data" 4 | 5 | type emptyHeaderV2Creator struct{} 6 | 7 | // NewEmptyHeaderV2Creator is able to create empty header v2 instances 8 | func NewEmptyHeaderV2Creator() *emptyHeaderV2Creator { 9 | return &emptyHeaderV2Creator{} 10 | } 11 | 12 | // CreateNewHeader creates a new empty header v2 13 | func (creator *emptyHeaderV2Creator) CreateNewHeader() data.HeaderHandler { 14 | return &HeaderV2{ 15 | Header: &Header{}, 16 | } 17 | } 18 | 19 | // IsInterfaceNil returns true if there is no value under the interface 20 | func (creator *emptyHeaderV2Creator) IsInterfaceNil() bool { 21 | return creator == nil 22 | } 23 | -------------------------------------------------------------------------------- /data/outport/feeInfo.go: -------------------------------------------------------------------------------- 1 | package outport 2 | 3 | import "math/big" 4 | 5 | // SetInitialPaidFee sets the initial paid fee 6 | func (f *FeeInfo) SetInitialPaidFee(fee *big.Int) { 7 | f.InitialPaidFee = fee 8 | } 9 | 10 | // SetGasUsed sets the used gas 11 | func (f *FeeInfo) SetGasUsed(gasUsed uint64) { 12 | f.GasUsed = gasUsed 13 | } 14 | 15 | // SetFee sets the fee 16 | func (f *FeeInfo) SetFee(fee *big.Int) { 17 | f.Fee = fee 18 | } 19 | 20 | // SetGasRefunded sets the gas units refunded 21 | func (f *FeeInfo) SetGasRefunded(gasRefunded uint64) { 22 | f.GasRefunded = gasRefunded 23 | } 24 | 25 | // SetHadRefund sets hadRefund field with true 26 | func (f *FeeInfo) SetHadRefund() { 27 | f.HadRefund = true 28 | } 29 | -------------------------------------------------------------------------------- /display/placeholders.go: -------------------------------------------------------------------------------- 1 | package display 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | const maxHeadlineLength = 100 9 | 10 | // Headline will build a headline message given a delimiter string 11 | // timestamp parameter will be printed before the repeating delimiter 12 | func Headline(message string, timestamp string, delimiter string) string { 13 | if len(delimiter) > 1 { 14 | delimiter = delimiter[:1] 15 | } 16 | if len(message) >= maxHeadlineLength { 17 | return message 18 | } 19 | delimiterLength := (maxHeadlineLength - len(message)) / 2 20 | delimiterText := strings.Repeat(delimiter, delimiterLength) 21 | return fmt.Sprintf("%s %s %s %s", timestamp, delimiterText, message, delimiterText) 22 | } 23 | -------------------------------------------------------------------------------- /data/block/emptyMetablockCreator_test.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/multiversx/mx-chain-core-go/core/check" 8 | "github.com/stretchr/testify/assert" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestNewEmptyMetaBlockCreator(t *testing.T) { 13 | t.Parallel() 14 | 15 | creator := NewEmptyMetaBlockCreator() 16 | require.False(t, check.IfNil(creator)) 17 | } 18 | 19 | func TestEmptyMetaBlockCreator_CreateNewHeader(t *testing.T) { 20 | t.Parallel() 21 | 22 | creator := NewEmptyMetaBlockCreator() 23 | header := creator.CreateNewHeader() 24 | require.False(t, check.IfNil(header)) 25 | assert.Equal(t, "*block.MetaBlock", fmt.Sprintf("%T", header)) 26 | } 27 | -------------------------------------------------------------------------------- /core/loggingFunctions_test.go: -------------------------------------------------------------------------------- 1 | package core_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/multiversx/mx-chain-core-go/core" 8 | "github.com/multiversx/mx-chain-core-go/core/mock" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestDumpGoRoutinesToLogShouldNotPanic(t *testing.T) { 13 | t.Parallel() 14 | 15 | defer func() { 16 | r := recover() 17 | if r != nil { 18 | require.Fail(t, fmt.Sprintf("should have not paniced %v", r)) 19 | } 20 | }() 21 | 22 | core.DumpGoRoutinesToLog(0, &mock.LoggerMock{}) 23 | } 24 | 25 | func TestGetRunningGoRoutines(t *testing.T) { 26 | t.Parallel() 27 | 28 | res := core.GetRunningGoRoutines(&mock.LoggerMock{}) 29 | require.NotNil(t, res) 30 | } 31 | -------------------------------------------------------------------------------- /data/receipt/receipt.proto: -------------------------------------------------------------------------------- 1 | 2 | syntax = "proto3"; 3 | 4 | package proto; 5 | 6 | option go_package = "github.com/multiversx/mx-chain-core-go/data/receipt;receipt"; 7 | option (gogoproto.stable_marshaler_all) = true; 8 | 9 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 10 | 11 | // Receipt holds all the data needed for a transaction receipt 12 | message Receipt { 13 | bytes Value = 1 [(gogoproto.jsontag) = "value", (gogoproto.casttypewith) = "math/big.Int;github.com/multiversx/mx-chain-core-go/data.BigIntCaster"]; 14 | bytes SndAddr = 2 [(gogoproto.jsontag) = "sender"]; 15 | bytes Data = 3 [(gogoproto.jsontag) = "data,omitempty"]; 16 | bytes TxHash = 4 [(gogoproto.jsontag) = "txHash"]; 17 | } 18 | -------------------------------------------------------------------------------- /core/epochFlags.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/multiversx/mx-chain-core-go/core/check" 7 | ) 8 | 9 | // EnableEpochFlag defines a flag specific to the enableEpochs.toml 10 | type EnableEpochFlag string 11 | 12 | // CheckHandlerCompatibility checks if the provided handler is compatible with this mx-chain-core-go version 13 | func CheckHandlerCompatibility(handler EnableEpochsHandler, requiredFlags []EnableEpochFlag) error { 14 | if check.IfNil(handler) { 15 | return ErrNilEnableEpochsHandler 16 | } 17 | 18 | for _, flag := range requiredFlags { 19 | if !handler.IsFlagDefined(flag) { 20 | return fmt.Errorf("%w for flag %s", ErrInvalidEnableEpochsHandler, flag) 21 | } 22 | } 23 | 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /core/check/ifHrp_test.go: -------------------------------------------------------------------------------- 1 | package check_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/multiversx/mx-chain-core-go/core/check" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestCheckIfHRP_ShouldWork(t *testing.T) { 11 | t.Parallel() 12 | 13 | assert.True(t, check.IfHrp("abc")) 14 | assert.True(t, check.IfHrp("Abc")) 15 | assert.False(t, check.IfHrp("abc1")) 16 | assert.False(t, check.IfHrp("abc/")) 17 | assert.False(t, check.IfHrp("/t")) 18 | assert.False(t, check.IfHrp("!t")) 19 | assert.False(t, check.IfHrp(".t")) 20 | assert.False(t, check.IfHrp("`t")) 21 | assert.False(t, check.IfHrp("")) 22 | assert.False(t, check.IfHrp("123()")) 23 | assert.False(t, check.IfHrp(" ")) 24 | assert.False(t, check.IfHrp(" ")) 25 | } 26 | -------------------------------------------------------------------------------- /core/mock/marshalizerStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // MarshalizerStub - 4 | type MarshalizerStub struct { 5 | MarshalCalled func(obj interface{}) ([]byte, error) 6 | UnmarshalCalled func(obj interface{}, buff []byte) error 7 | } 8 | 9 | // Marshal - 10 | func (ms *MarshalizerStub) Marshal(obj interface{}) ([]byte, error) { 11 | if ms.MarshalCalled != nil { 12 | return ms.MarshalCalled(obj) 13 | } 14 | 15 | return nil, nil 16 | } 17 | 18 | // Unmarshal - 19 | func (ms *MarshalizerStub) Unmarshal(obj interface{}, buff []byte) error { 20 | if ms.UnmarshalCalled != nil { 21 | return ms.UnmarshalCalled(obj, buff) 22 | } 23 | 24 | return nil 25 | } 26 | 27 | // IsInterfaceNil - 28 | func (ms *MarshalizerStub) IsInterfaceNil() bool { 29 | return ms == nil 30 | } 31 | -------------------------------------------------------------------------------- /core/watchdog/disabledWatchDog.go: -------------------------------------------------------------------------------- 1 | package watchdog 2 | 3 | import "time" 4 | 5 | // DisabledWatchdog represents a disabled WatchdogTimer implementation 6 | type DisabledWatchdog struct { 7 | } 8 | 9 | // Set does nothing 10 | func (dw *DisabledWatchdog) Set(_ func(alarmID string), _ time.Duration, _ string) { 11 | } 12 | 13 | // SetDefault does nothing 14 | func (dw *DisabledWatchdog) SetDefault(_ time.Duration, _ string) { 15 | } 16 | 17 | // Stop does nothing 18 | func (dw *DisabledWatchdog) Stop(_ string) { 19 | } 20 | 21 | // Reset does nothing 22 | func (dw *DisabledWatchdog) Reset(_ string) { 23 | } 24 | 25 | // IsInterfaceNil returns true if there is no value under the interface 26 | func (dw *DisabledWatchdog) IsInterfaceNil() bool { 27 | return dw == nil 28 | } 29 | -------------------------------------------------------------------------------- /data/mock/hasherStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // HasherStub - 4 | type HasherStub struct { 5 | ComputeCalled func(s string) []byte 6 | EmptyHashCalled func() []byte 7 | } 8 | 9 | // Compute - 10 | func (hash *HasherStub) Compute(s string) []byte { 11 | if hash.ComputeCalled != nil { 12 | return hash.ComputeCalled(s) 13 | } 14 | 15 | return nil 16 | } 17 | 18 | // EmptyHash - 19 | func (hash *HasherStub) EmptyHash() []byte { 20 | if hash.EmptyHashCalled != nil { 21 | hash.EmptyHashCalled() 22 | } 23 | 24 | return nil 25 | } 26 | 27 | // Size - 28 | func (hash *HasherStub) Size() int { 29 | return 0 30 | } 31 | 32 | // IsInterfaceNil returns true if there is no value under the interface 33 | func (hash *HasherStub) IsInterfaceNil() bool { 34 | return hash == nil 35 | } 36 | -------------------------------------------------------------------------------- /data/vm/callType_test.go: -------------------------------------------------------------------------------- 1 | package vm 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func TestCallType_ToString(t *testing.T) { 10 | callType := DirectCall 11 | require.Equal(t, DirectCallStr, callType.ToString()) 12 | 13 | callType = AsynchronousCall 14 | require.Equal(t, AsynchronousCallStr, callType.ToString()) 15 | 16 | callType = AsynchronousCallBack 17 | require.Equal(t, AsynchronousCallBackStr, callType.ToString()) 18 | 19 | callType = ESDTTransferAndExecute 20 | require.Equal(t, ESDTTransferAndExecuteStr, callType.ToString()) 21 | 22 | callType = ExecOnDestByCaller 23 | require.Equal(t, ExecOnDestByCallerStr, callType.ToString()) 24 | 25 | callType = CallType(9999) 26 | require.Equal(t, UnknownStr, callType.ToString()) 27 | } 28 | -------------------------------------------------------------------------------- /core/random/concurrentSafeIntRandomizer.go: -------------------------------------------------------------------------------- 1 | package random 2 | 3 | import ( 4 | "crypto/rand" 5 | "encoding/binary" 6 | ) 7 | 8 | // ConcurrentSafeIntRandomizer implements dataRetriever.IntRandomizer and can be accessed in a concurrent manner 9 | type ConcurrentSafeIntRandomizer struct { 10 | } 11 | 12 | // Intn returns an int in [0, n) interval 13 | func (csir *ConcurrentSafeIntRandomizer) Intn(n int) int { 14 | if n <= 0 { 15 | return 0 16 | } 17 | 18 | buff := make([]byte, 8) 19 | _, _ = rand.Reader.Read(buff) 20 | valUint64 := binary.BigEndian.Uint64(buff) 21 | 22 | return int(valUint64 % uint64(n)) 23 | } 24 | 25 | // IsInterfaceNil returns true if there is no value under the interface 26 | func (csir *ConcurrentSafeIntRandomizer) IsInterfaceNil() bool { 27 | return csir == nil 28 | } 29 | -------------------------------------------------------------------------------- /data/block/unmarshal.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import ( 4 | "github.com/multiversx/mx-chain-core-go/core/check" 5 | "github.com/multiversx/mx-chain-core-go/data" 6 | "github.com/multiversx/mx-chain-core-go/marshal" 7 | ) 8 | 9 | // GetHeaderFromBytes will unmarshal the header bytes based on the header type 10 | func GetHeaderFromBytes(marshaller marshal.Marshalizer, creator EmptyBlockCreator, headerBytes []byte) (data.HeaderHandler, error) { 11 | if check.IfNil(marshaller) { 12 | return nil, data.ErrNilMarshalizer 13 | } 14 | if check.IfNil(creator) { 15 | return nil, data.ErrNilEmptyBlockCreator 16 | } 17 | 18 | header := creator.CreateNewHeader() 19 | err := marshaller.Unmarshal(header, headerBytes) 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | return header, nil 25 | } 26 | -------------------------------------------------------------------------------- /data/transaction/log.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=$GOPATH/src log.proto 2 | package transaction 3 | 4 | import ( 5 | "github.com/multiversx/mx-chain-core-go/data" 6 | ) 7 | 8 | // GetLogEvents returns the interface for the underlying events of the log structure 9 | func (l *Log) GetLogEvents() []data.EventHandler { 10 | events := make([]data.EventHandler, len(l.Events)) 11 | for i, e := range l.Events { 12 | events[i] = e 13 | } 14 | return events 15 | } 16 | 17 | // IsInterfaceNil verifies if underlying object is nil 18 | func (l *Log) IsInterfaceNil() bool { 19 | return l == nil 20 | } 21 | 22 | // IsInterfaceNil verifies if underlying object is nil 23 | func (e *Event) IsInterfaceNil() bool { 24 | return e == nil 25 | } 26 | -------------------------------------------------------------------------------- /data/api/apiAccountResponse.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | // AccountResponse is the data transfer object to be returned on API when requesting an address data 4 | type AccountResponse struct { 5 | Address string `json:"address"` 6 | Nonce uint64 `json:"nonce"` 7 | Balance string `json:"balance"` 8 | Username string `json:"username"` 9 | Code string `json:"code"` 10 | CodeHash []byte `json:"codeHash"` 11 | RootHash []byte `json:"rootHash"` 12 | CodeMetadata []byte `json:"codeMetadata"` 13 | DeveloperReward string `json:"developerReward"` 14 | OwnerAddress string `json:"ownerAddress"` 15 | Pairs map[string]string `json:"pairs,omitempty"` 16 | } 17 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/multiversx/mx-chain-core-go 2 | 3 | go 1.23 4 | 5 | require ( 6 | github.com/btcsuite/btcd/btcutil v1.1.3 7 | github.com/denisbrodbeck/machineid v1.0.1 8 | github.com/gogo/protobuf v1.3.2 9 | github.com/golang/protobuf v1.5.2 10 | github.com/mr-tron/base58 v1.2.0 11 | github.com/pelletier/go-toml v1.9.3 12 | github.com/pkg/errors v0.9.1 13 | github.com/stretchr/testify v1.7.0 14 | golang.org/x/crypto v0.3.0 15 | ) 16 | 17 | require ( 18 | github.com/davecgh/go-spew v1.1.1 // indirect 19 | github.com/pmezard/go-difflib v1.0.0 // indirect 20 | golang.org/x/sys v0.2.0 // indirect 21 | google.golang.org/protobuf v1.26.0 // indirect 22 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect 23 | ) 24 | 25 | replace github.com/gogo/protobuf => github.com/multiversx/protobuf v1.3.2 26 | -------------------------------------------------------------------------------- /marshal/errors.go: -------------------------------------------------------------------------------- 1 | package marshal 2 | 3 | import "errors" 4 | 5 | // ErrMarshallingProto is raised when the object does not implement proto.Message 6 | var ErrMarshallingProto = errors.New("can not serialize the object") 7 | 8 | // ErrUnmarshallingProto is raised when the object that needs to be unmarshaled does not implement proto.Message 9 | var ErrUnmarshallingProto = errors.New("obj does not implement proto.Message") 10 | 11 | // ErrUnmarshallingBadSize is raised when the provided serialized data size exceeds the re-serialized data size 12 | // plus an additional provided delta 13 | var ErrUnmarshallingBadSize = errors.New("imput buffer too long") 14 | 15 | // ErrUnknownMarshalizer signals that the specified marshalizer does not have a ready to use implementation 16 | var ErrUnknownMarshalizer = errors.New("unknown marshalizer") 17 | -------------------------------------------------------------------------------- /data/block/emptyHeaderV2Creator_test.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/multiversx/mx-chain-core-go/core/check" 8 | "github.com/stretchr/testify/assert" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestNewEmptyHeaderV2Creator(t *testing.T) { 13 | t.Parallel() 14 | 15 | creator := NewEmptyHeaderV2Creator() 16 | require.False(t, check.IfNil(creator)) 17 | } 18 | 19 | func TestEmptyHeaderV2Creator_CreateNewHeader(t *testing.T) { 20 | t.Parallel() 21 | 22 | creator := NewEmptyHeaderV2Creator() 23 | header := creator.CreateNewHeader() 24 | require.False(t, check.IfNil(header)) 25 | require.False(t, check.IfNil(header.(*HeaderV2))) 26 | require.False(t, check.IfNil(header.(*HeaderV2).Header)) 27 | assert.Equal(t, "*block.HeaderV2", fmt.Sprintf("%T", header)) 28 | } 29 | -------------------------------------------------------------------------------- /data/transaction/status.go: -------------------------------------------------------------------------------- 1 | package transaction 2 | 3 | // TxStatus is the status of a transaction 4 | type TxStatus string 5 | 6 | const ( 7 | // TxStatusPending = received and maybe executed on source shard, but not on destination shard 8 | TxStatusPending TxStatus = "pending" 9 | // TxStatusSuccess = received and executed 10 | TxStatusSuccess TxStatus = "success" 11 | // TxStatusFail = received and executed with error 12 | TxStatusFail TxStatus = "fail" 13 | // TxStatusInvalid = considered invalid 14 | TxStatusInvalid TxStatus = "invalid" 15 | // TxStatusRewardReverted represents the identifier for a reverted reward transaction 16 | TxStatusRewardReverted TxStatus = "reward-reverted" 17 | ) 18 | 19 | // String returns the string representation of the status 20 | func (tx TxStatus) String() string { 21 | return string(tx) 22 | } 23 | -------------------------------------------------------------------------------- /core/atomic/flag.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import "sync/atomic" 4 | 5 | // Flag is an atomic flag 6 | type Flag struct { 7 | value uint32 8 | } 9 | 10 | // SetReturningPrevious sets flag and returns its previous value 11 | func (flag *Flag) SetReturningPrevious() bool { 12 | previousValue := atomic.SwapUint32(&flag.value, 1) 13 | return previousValue == 1 14 | } 15 | 16 | // Reset resets the flag, putting it in off position 17 | func (flag *Flag) Reset() { 18 | atomic.StoreUint32(&flag.value, 0) 19 | } 20 | 21 | // IsSet checks whether flag is set 22 | func (flag *Flag) IsSet() bool { 23 | value := atomic.LoadUint32(&flag.value) 24 | return value == 1 25 | } 26 | 27 | // SetValue sets the new value in the flag 28 | func (flag *Flag) SetValue(newValue bool) { 29 | if newValue { 30 | _ = flag.SetReturningPrevious() 31 | } else { 32 | flag.Reset() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /core/mock/hasherStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // HasherStub - 4 | type HasherStub struct { 5 | ComputeCalled func(s string) []byte 6 | EmptyHashCalled func() []byte 7 | SizeCalled func() int 8 | } 9 | 10 | // Compute - 11 | func (hash *HasherStub) Compute(s string) []byte { 12 | if hash.ComputeCalled != nil { 13 | return hash.ComputeCalled(s) 14 | } 15 | return nil 16 | } 17 | 18 | // EmptyHash - 19 | func (hash *HasherStub) EmptyHash() []byte { 20 | if hash.EmptyHashCalled != nil { 21 | hash.EmptyHashCalled() 22 | } 23 | return nil 24 | } 25 | 26 | // Size - 27 | func (hash *HasherStub) Size() int { 28 | if hash.SizeCalled != nil { 29 | return hash.SizeCalled() 30 | } 31 | 32 | return 0 33 | } 34 | 35 | // IsInterfaceNil returns true if there is no value under the interface 36 | func (hash *HasherStub) IsInterfaceNil() bool { 37 | return false 38 | } 39 | -------------------------------------------------------------------------------- /core/mock/statusHandlerMock.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // StatusHandlerMock - 4 | type StatusHandlerMock struct { 5 | } 6 | 7 | // Increment - 8 | func (s *StatusHandlerMock) Increment(_ string) { 9 | } 10 | 11 | // AddUint64 - 12 | func (s *StatusHandlerMock) AddUint64(_ string, _ uint64) { 13 | } 14 | 15 | // Decrement - 16 | func (s *StatusHandlerMock) Decrement(_ string) { 17 | } 18 | 19 | // SetInt64Value - 20 | func (s *StatusHandlerMock) SetInt64Value(_ string, _ int64) { 21 | } 22 | 23 | // SetUInt64Value - 24 | func (s *StatusHandlerMock) SetUInt64Value(_ string, _ uint64) { 25 | } 26 | 27 | // SetStringValue - 28 | func (s *StatusHandlerMock) SetStringValue(_ string, _ string) { 29 | } 30 | 31 | // Close - 32 | func (s *StatusHandlerMock) Close() { 33 | } 34 | 35 | // IsInterfaceNil - 36 | func (s *StatusHandlerMock) IsInterfaceNil() bool { 37 | return false 38 | } 39 | -------------------------------------------------------------------------------- /core/keyLoader.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | // keyLoader holds the logic for loading a key from a file and an index 4 | type keyLoader struct { 5 | } 6 | 7 | // NewKeyLoader creates a new instance of type key loader 8 | func NewKeyLoader() *keyLoader { 9 | return &keyLoader{} 10 | } 11 | 12 | // LoadKey loads the key with the given index found in the pem file from the given path. 13 | func (kl *keyLoader) LoadKey(path string, skIndex int) ([]byte, string, error) { 14 | return LoadSkPkFromPemFile(path, skIndex) 15 | } 16 | 17 | // LoadAllKeys loads all keys found in the pem file for the given path 18 | func (kl *keyLoader) LoadAllKeys(path string) ([][]byte, []string, error) { 19 | return LoadAllKeysFromPemFile(path) 20 | } 21 | 22 | // IsInterfaceNil returns true if there is no value under the interface 23 | func (kl *keyLoader) IsInterfaceNil() bool { 24 | return kl == nil 25 | } 26 | -------------------------------------------------------------------------------- /core/sync/rwmutex_test.go: -------------------------------------------------------------------------------- 1 | package sync 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func TestNewRWMutex(t *testing.T) { 10 | t.Parallel() 11 | 12 | rwm := newRWMutex() 13 | require.NotNil(t, rwm) 14 | require.Equal(t, int32(0), rwm.cntLocks) 15 | require.Equal(t, int32(0), rwm.cntRLocks) 16 | } 17 | 18 | func TestRWMutex_Lock_Unlock_IsLocked_NumLocks(t *testing.T) { 19 | t.Parallel() 20 | 21 | rwm := &rwMutex{} 22 | rwm.lock() 23 | rwm.updateCounterLock() 24 | require.Equal(t, int32(1), rwm.numLocks()) 25 | 26 | rwm.unlock() 27 | rwm.updateCounterUnlock() 28 | require.Equal(t, int32(0), rwm.numLocks()) 29 | 30 | rwm.rLock() 31 | rwm.updateCounterRLock() 32 | require.Equal(t, int32(1), rwm.numLocks()) 33 | 34 | rwm.rUnlock() 35 | rwm.updateCounterRUnlock() 36 | require.Equal(t, int32(0), rwm.numLocks()) 37 | } 38 | -------------------------------------------------------------------------------- /core/queue/hashQueue.go: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import "sync" 4 | 5 | type sliceQueue struct { 6 | queue [][]byte 7 | size uint 8 | *sync.RWMutex 9 | } 10 | 11 | // NewSliceQueue creates a new sliceQueue 12 | func NewSliceQueue(numHashes uint) *sliceQueue { 13 | return &sliceQueue{ 14 | queue: make([][]byte, 0), 15 | size: numHashes, 16 | RWMutex: &sync.RWMutex{}, 17 | } 18 | } 19 | 20 | // Add adds a new element to the queue, and evicts the first element if the queue is full 21 | func (hq *sliceQueue) Add(data []byte) []byte { 22 | if hq.size == 0 { 23 | return data 24 | } 25 | 26 | hq.Lock() 27 | defer hq.Unlock() 28 | 29 | if uint(len(hq.queue)) == hq.size { 30 | dataToEvict := hq.queue[0] 31 | hq.queue = hq.queue[1:] 32 | hq.queue = append(hq.queue, data) 33 | 34 | return dataToEvict 35 | } 36 | 37 | hq.queue = append(hq.queue, data) 38 | 39 | return nil 40 | } 41 | -------------------------------------------------------------------------------- /data/transaction/apiTransactionResult_test.go: -------------------------------------------------------------------------------- 1 | package transaction 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestCostResponseStructure(t *testing.T) { 11 | t.Parallel() 12 | 13 | costResponse := &CostResponse{ 14 | GasUnits: 10000, 15 | ReturnMessage: "", 16 | } 17 | 18 | costResponseBytes, err := json.Marshal(costResponse) 19 | require.Nil(t, err) 20 | require.NotNil(t, costResponseBytes) 21 | 22 | costResponseMap := make(map[string]interface{}) 23 | err = json.Unmarshal(costResponseBytes, &costResponseMap) 24 | require.Nil(t, err) 25 | 26 | // DO NOT CHANGE THIS CONST IN ORDER TO KEEP THE BACKWARDS COMPATIBILITY 27 | keyForGasUnits := "txGasUnits" 28 | gasUnitsFloat, ok := costResponseMap[keyForGasUnits].(float64) 29 | require.True(t, ok) 30 | require.Equal(t, uint64(10000), uint64(gasUnitsFloat)) 31 | } 32 | -------------------------------------------------------------------------------- /core/check/ifZero.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "reflect" 7 | ) 8 | 9 | // ForZeroUintFields checks if fields are uint64 and whether are greater than 0 10 | func ForZeroUintFields(arg interface{}) error { 11 | v := reflect.ValueOf(arg) 12 | for i := 0; i < v.NumField(); i++ { 13 | field := v.Field(i) 14 | if field.Kind() != reflect.Uint64 && 15 | field.Kind() != reflect.Uint32 && 16 | field.Kind() != reflect.Uint { 17 | continue 18 | } 19 | if field.Uint() == 0 { 20 | name := v.Type().Field(i).Name 21 | return fmt.Errorf("gas cost for operation %s has been set to 0 or is not set", name) 22 | } 23 | } 24 | 25 | return nil 26 | } 27 | 28 | // IsZeroFloat64 returns true if the provided absolute value is less than provided absolute epsilon 29 | func IsZeroFloat64(value float64, epsilon float64) bool { 30 | return math.Abs(value) <= math.Abs(epsilon) 31 | } 32 | -------------------------------------------------------------------------------- /core/mock/hasherMock.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import "crypto/sha256" 4 | 5 | var sha256EmptyHash []byte 6 | 7 | // HasherMock that will be used for testing 8 | type HasherMock struct { 9 | } 10 | 11 | // Compute will output the SHA's equivalent of the input string 12 | func (sha HasherMock) Compute(s string) []byte { 13 | h := sha256.New() 14 | _, _ = h.Write([]byte(s)) 15 | return h.Sum(nil) 16 | } 17 | 18 | // EmptyHash will return the equivalent of empty string SHA's 19 | func (sha HasherMock) EmptyHash() []byte { 20 | if len(sha256EmptyHash) == 0 { 21 | sha256EmptyHash = sha.Compute("") 22 | } 23 | return sha256EmptyHash 24 | } 25 | 26 | // Size returns the required size in bytes 27 | func (HasherMock) Size() int { 28 | return sha256.Size 29 | } 30 | 31 | // IsInterfaceNil returns true if there is no value under the interface 32 | func (sha HasherMock) IsInterfaceNil() bool { 33 | return false 34 | } 35 | -------------------------------------------------------------------------------- /data/mock/hasherMock.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import "crypto/sha256" 4 | 5 | var sha256EmptyHash []byte 6 | 7 | // HasherMock that will be used for testing 8 | type HasherMock struct { 9 | } 10 | 11 | // Compute will output the SHA's equivalent of the input string 12 | func (sha HasherMock) Compute(s string) []byte { 13 | h := sha256.New() 14 | _, _ = h.Write([]byte(s)) 15 | return h.Sum(nil) 16 | } 17 | 18 | // EmptyHash will return the equivalent of empty string SHA's 19 | func (sha HasherMock) EmptyHash() []byte { 20 | if len(sha256EmptyHash) == 0 { 21 | sha256EmptyHash = sha.Compute("") 22 | } 23 | return sha256EmptyHash 24 | } 25 | 26 | // Size return the required size in bytes 27 | func (HasherMock) Size() int { 28 | return sha256.Size 29 | } 30 | 31 | // IsInterfaceNil returns true if there is no value under the interface 32 | func (sha HasherMock) IsInterfaceNil() bool { 33 | return false 34 | } 35 | -------------------------------------------------------------------------------- /data/generatedCode.md: -------------------------------------------------------------------------------- 1 | ### Data structure definition ### 2 | 3 | The usual message definition consists of: 4 | 5 | ``` 6 | message/ 7 | ├── proto 8 | │   └── message.proto 9 | ├── message.go 10 | └── message.pb.go [generated] 11 | ``` 12 | 13 | #### message.proto #### 14 | 15 | Contains the protobuf message definition (with gogo/protobuf extensions) 16 | 17 | #### message.go #### 18 | 19 | Should contain the go generate directive 20 | 21 | ``` 22 | //go:generate protoc -I=proto -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=. message.proto 23 | ``` 24 | 25 | And any necessary methods that are not generated. 26 | 27 | #### Generating code #### 28 | 29 | Check [gogo protobuf geting started](https://github.com/multiversx/protobuf#getting-started) for initial setup. 30 | 31 | To regenerate all the data structures run: 32 | ``` 33 | go generate ./... 34 | ``` 35 | in the project root. 36 | 37 | -------------------------------------------------------------------------------- /core/pubkeyConverter/errors.go: -------------------------------------------------------------------------------- 1 | package pubkeyConverter 2 | 3 | import "errors" 4 | 5 | // ErrInvalidAddressLength signals that address length is invalid 6 | var ErrInvalidAddressLength = errors.New("invalid address length") 7 | 8 | // ErrWrongSize signals that a wrong size occurred 9 | var ErrWrongSize = errors.New("wrong size") 10 | 11 | // ErrInvalidErdAddress signals that the provided address is not an ERD address 12 | var ErrInvalidErdAddress = errors.New("invalid ERD address") 13 | 14 | // ErrBech32ConvertError signals that conversion the 5bit alphabet to 8bit failed 15 | var ErrBech32ConvertError = errors.New("can't convert bech32 string") 16 | 17 | // ErrHrpPrefix signals that the prefix is not human readable or empty 18 | var ErrInvalidHrpPrefix = errors.New("invalid hrp prefix") 19 | 20 | // ErrConvertBits signals that a configuration mistake has been introduced 21 | var ErrConvertBits = errors.New("invalid fromBits or toBits when converting bits") 22 | -------------------------------------------------------------------------------- /data/transaction/constants.go: -------------------------------------------------------------------------------- 1 | package transaction 2 | 3 | // TxType represents a transaction type 4 | type TxType string 5 | 6 | const ( 7 | // TxTypeNormal represents the identifier for a regular transaction 8 | TxTypeNormal TxType = "normal" 9 | 10 | // TxTypeUnsigned represents the identifier for a unsigned transaction 11 | TxTypeUnsigned TxType = "unsigned" 12 | 13 | // TxTypeReward represents the identifier for a reward transaction 14 | TxTypeReward TxType = "reward" 15 | 16 | // TxTypeInvalid represents the identifier for an invalid transaction 17 | TxTypeInvalid TxType = "invalid" 18 | ) 19 | 20 | // MaskSignedWithHash - this mask is used to verify if LSB from last byte from field options from transaction is set 21 | const MaskSignedWithHash = uint32(1) 22 | 23 | // MaskGuardedTransaction - this mask is used to verify if the flag for guarded transaction is set in the transaction option field 24 | const MaskGuardedTransaction = uint32(1) << 1 25 | -------------------------------------------------------------------------------- /data/transaction/errors.go: -------------------------------------------------------------------------------- 1 | package transaction 2 | 3 | import "errors" 4 | 5 | // ErrNilEncoder signals that a nil encoder has been provided 6 | var ErrNilEncoder = errors.New("nil encoder") 7 | 8 | // ErrNilMarshalizer signals that a nil marshalizer has been provided 9 | var ErrNilMarshalizer = errors.New("nil marshalizer") 10 | 11 | // ErrNilHasher signals that a nil hasher has been provided 12 | var ErrNilHasher = errors.New("nil hasher") 13 | 14 | // ErrNilApiTransactionResult signals that a nil api transaction result has been provided 15 | var ErrNilApiTransactionResult = errors.New("nil ApiTransactionResult") 16 | 17 | // ErrNilApiTransactionResult signals that a nil api transaction result has been provided 18 | var ErrNilUint64ByteSliceConverter = errors.New("nil Uint64ByteSliceConverter") 19 | 20 | // ErrNilApiTransactionResult signals that a nil api transaction result has been provided 21 | var ErrNiStorageService = errors.New("nil StorageService") 22 | -------------------------------------------------------------------------------- /core/closing/safeChanCloser.go: -------------------------------------------------------------------------------- 1 | package closing 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | type safeChanCloser struct { 8 | closeMut sync.Mutex 9 | chClose chan struct{} 10 | } 11 | 12 | // NewSafeChanCloser returns a safe chan closer instance 13 | func NewSafeChanCloser() *safeChanCloser { 14 | return &safeChanCloser{ 15 | chClose: make(chan struct{}), 16 | } 17 | } 18 | 19 | // Close will close the channel in a safe concurrent manner 20 | func (closer *safeChanCloser) Close() { 21 | closer.closeMut.Lock() 22 | defer closer.closeMut.Unlock() 23 | 24 | select { 25 | case <-closer.chClose: 26 | return 27 | default: 28 | close(closer.chClose) 29 | } 30 | } 31 | 32 | // ChanClose returns the closing channel 33 | func (closer *safeChanCloser) ChanClose() <-chan struct{} { 34 | return closer.chClose 35 | } 36 | 37 | // IsInterfaceNil returns true if there is no value under the interface 38 | func (closer *safeChanCloser) IsInterfaceNil() bool { 39 | return closer == nil 40 | } 41 | -------------------------------------------------------------------------------- /display/errors.go: -------------------------------------------------------------------------------- 1 | package display 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | // ErrNilHeader signals that a nil header slice has been provided 8 | var ErrNilHeader = errors.New("nil header") 9 | 10 | // ErrNilDataLines signals that a nil data lines slice has been provided 11 | var ErrNilDataLines = errors.New("nil lineData slice") 12 | 13 | // ErrEmptySlices signals that empty slices has been provided 14 | var ErrEmptySlices = errors.New("empty slices") 15 | 16 | // ErrNilLineDataInSlice signals that a nil line data element was found in slice 17 | var ErrNilLineDataInSlice = errors.New("nil line data element found in slice") 18 | 19 | // ErrNilValuesOfLineDataInSlice signals that a line data element has nil values 20 | var ErrNilValuesOfLineDataInSlice = errors.New("nil line data values slice found") 21 | 22 | // ErrNilDisplayByteSliceHandler signals that a nil display byte slice handler has been provided 23 | var ErrNilDisplayByteSliceHandler = errors.New("nil display byte slice handler") 24 | -------------------------------------------------------------------------------- /data/receipt/receipt_test.go: -------------------------------------------------------------------------------- 1 | package receipt_test 2 | 3 | import ( 4 | "math/big" 5 | "testing" 6 | 7 | "github.com/multiversx/mx-chain-core-go/data/receipt" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestReceipt_SettersAndGetters(t *testing.T) { 12 | t.Parallel() 13 | 14 | r := receipt.Receipt{} 15 | 16 | data := []byte("data") 17 | value := big.NewInt(37) 18 | addr := []byte("addr") 19 | 20 | r.SetData(data) 21 | r.SetValue(value) 22 | r.SetRcvAddr(addr) 23 | r.SetSndAddr(addr) 24 | 25 | assert.Equal(t, data, r.GetData()) 26 | assert.Equal(t, value, r.GetValue()) 27 | assert.Equal(t, addr, r.GetRcvAddr()) 28 | assert.Equal(t, addr, r.GetSndAddr()) 29 | assert.Equal(t, uint64(0), r.GetNonce()) 30 | assert.Equal(t, uint64(0), r.GetGasPrice()) 31 | assert.Equal(t, uint64(0), r.GetGasLimit()) 32 | } 33 | 34 | func TestReceipt_CheckIntegrityReturnsNil(t *testing.T) { 35 | r := receipt.Receipt{} 36 | 37 | err := r.CheckIntegrity() 38 | assert.Nil(t, err) 39 | } 40 | -------------------------------------------------------------------------------- /core/loggingFunctions.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "bytes" 5 | "runtime" 6 | "runtime/pprof" 7 | ) 8 | 9 | // DumpGoRoutinesToLog will print the currently running go routines in the log 10 | func DumpGoRoutinesToLog(goRoutinesNumberStart int, log Logger) { 11 | if log == nil { 12 | return 13 | } 14 | 15 | buf := new(bytes.Buffer) 16 | err := pprof.Lookup("goroutine").WriteTo(buf, 2) 17 | if err != nil { 18 | log.Error("could not dump goroutines", "error", err) 19 | } 20 | log.Debug("go routines number", 21 | "start", goRoutinesNumberStart, 22 | "end", runtime.NumGoroutine()) 23 | 24 | log.Debug(buf.String()) 25 | } 26 | 27 | // GetRunningGoRoutines gets the currently running go routines stack trace as a bytes.Buffer 28 | func GetRunningGoRoutines(log Logger) *bytes.Buffer { 29 | buffer := new(bytes.Buffer) 30 | err := pprof.Lookup("goroutine").WriteTo(buffer, 2) 31 | if err != nil { 32 | log.Error("could not dump goroutines", "error", err) 33 | } 34 | return buffer 35 | } 36 | -------------------------------------------------------------------------------- /core/nodetype/nodeTypeProvider.go: -------------------------------------------------------------------------------- 1 | package nodetype 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/multiversx/mx-chain-core-go/core" 7 | ) 8 | 9 | type nodeTypeProvider struct { 10 | sync.RWMutex 11 | nodeType core.NodeType 12 | } 13 | 14 | // NewNodeTypeProvider returns a new instance of nodeTypeProvider 15 | func NewNodeTypeProvider(initialType core.NodeType) *nodeTypeProvider { 16 | return &nodeTypeProvider{ 17 | nodeType: initialType, 18 | } 19 | } 20 | 21 | // SetType will update the internal node type 22 | func (ntp *nodeTypeProvider) SetType(nodeType core.NodeType) { 23 | ntp.Lock() 24 | ntp.nodeType = nodeType 25 | ntp.Unlock() 26 | } 27 | 28 | // GetType returns the node type 29 | func (ntp *nodeTypeProvider) GetType() core.NodeType { 30 | ntp.RLock() 31 | defer ntp.RUnlock() 32 | 33 | return ntp.nodeType 34 | } 35 | 36 | // IsInterfaceNil returns true if there is no value under the interface 37 | func (ntp *nodeTypeProvider) IsInterfaceNil() bool { 38 | return ntp == nil 39 | } 40 | -------------------------------------------------------------------------------- /data/mock/nonceHashConverterMock.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import ( 4 | "encoding/binary" 5 | "errors" 6 | ) 7 | 8 | type nonceHashConverterMock struct { 9 | } 10 | 11 | // NewNonceHashConverterMock - 12 | func NewNonceHashConverterMock() *nonceHashConverterMock { 13 | return &nonceHashConverterMock{} 14 | } 15 | 16 | // ToByteSlice - 17 | func (*nonceHashConverterMock) ToByteSlice(value uint64) []byte { 18 | buff := make([]byte, 8) 19 | 20 | binary.BigEndian.PutUint64(buff, value) 21 | 22 | return buff 23 | } 24 | 25 | // ToUint64 - 26 | func (*nonceHashConverterMock) ToUint64(buff []byte) (uint64, error) { 27 | if buff == nil { 28 | return 0, errors.New("failure, nil slice") 29 | } 30 | 31 | if len(buff) != 8 { 32 | return 0, errors.New("failure, len not 8") 33 | } 34 | 35 | return binary.BigEndian.Uint64(buff), nil 36 | } 37 | 38 | // IsInterfaceNil returns true if there is no value under the interface 39 | func (nhcm *nonceHashConverterMock) IsInterfaceNil() bool { 40 | return nhcm == nil 41 | } 42 | -------------------------------------------------------------------------------- /marshal/factory/marshalizerFactory.go: -------------------------------------------------------------------------------- 1 | package factory 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/multiversx/mx-chain-core-go/marshal" 7 | ) 8 | 9 | // JsonMarshalizer is the name reserved for the json marshalizer 10 | const JsonMarshalizer = "json" 11 | 12 | // TxJsonMarshalizer is the name reserved for the transaction json marshalizer 13 | const TxJsonMarshalizer = "tx-json" 14 | 15 | // GogoProtobuf is the name reserved for the gogoslick protobuf marshalizer 16 | const GogoProtobuf = "gogo protobuf" 17 | 18 | // NewMarshalizer creates a new marshalizer instance based on the provided parameters 19 | func NewMarshalizer(name string) (marshal.Marshalizer, error) { 20 | switch name { 21 | case JsonMarshalizer: 22 | return &marshal.JsonMarshalizer{}, nil 23 | case GogoProtobuf: 24 | return &marshal.GogoProtoMarshalizer{}, nil 25 | case TxJsonMarshalizer: 26 | return &marshal.TxJsonMarshalizer{}, nil 27 | default: 28 | return nil, fmt.Errorf("%w '%s'", marshal.ErrUnknownMarshalizer, name) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /data/block/headerProof.proto: -------------------------------------------------------------------------------- 1 | // This file holds the data structures related with the functionality of a shard block V2 2 | syntax = "proto3"; 3 | 4 | package proto; 5 | 6 | option go_package = "block"; 7 | option (gogoproto.stable_marshaler_all) = true; 8 | 9 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 10 | 11 | // HeaderProof defines a proof for a specific header 12 | message HeaderProof { 13 | bytes PubKeysBitmap = 1 [(gogoproto.jsontag) = "pubKeysBitmap"]; 14 | bytes AggregatedSignature = 2 [(gogoproto.jsontag) = "aggregatedSignature"]; 15 | bytes HeaderHash = 3 [(gogoproto.jsontag) = "headerHash"]; 16 | uint32 HeaderEpoch = 4 [(gogoproto.jsontag) = "headerEpoch"]; 17 | uint64 HeaderNonce = 5 [(gogoproto.jsontag) = "headerNonce"]; 18 | uint32 HeaderShardId = 6 [(gogoproto.jsontag) = "headerShardId"]; 19 | uint64 HeaderRound = 7 [(gogoproto.jsontag) = "headerRound"]; 20 | bool IsStartOfEpoch = 8 [(gogoproto.jsontag) = "isStartOfEpoch"]; 21 | } 22 | -------------------------------------------------------------------------------- /marshal/txJsonMarshalizer_test.go: -------------------------------------------------------------------------------- 1 | package marshal 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | type TestTxStruct struct { 11 | Sender string `json:"sender"` 12 | Receiver string `json:"receiver"` 13 | Nonce uint64 `json:"nonce"` 14 | Data string `json:"data"` 15 | } 16 | 17 | func TestTxJsonMarshalizer_MarshalUnmarshalWithCharactersThatCouldBeEncoded(t *testing.T) { 18 | t.Parallel() 19 | 20 | tx := &TestTxStruct{ 21 | Sender: "sndr", 22 | Receiver: "rcvr", 23 | Nonce: 10, 24 | Data: "data@~`!@#$^&*()_=[]{};'<>?,./|<>> 0 { 37 | returningBuff = append(returningBuff, elements) 38 | } 39 | 40 | return returningBuff, nil 41 | } 42 | -------------------------------------------------------------------------------- /marshal/jsonMarshalizer.go: -------------------------------------------------------------------------------- 1 | package marshal 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | ) 7 | 8 | var _ Marshalizer = (*JsonMarshalizer)(nil) 9 | 10 | // JsonMarshalizer implements Marshalizer interface using JSON format 11 | type JsonMarshalizer struct { 12 | } 13 | 14 | // Marshal tries to serialize obj parameter 15 | func (jm JsonMarshalizer) Marshal(obj interface{}) ([]byte, error) { 16 | if obj == nil { 17 | return nil, errors.New("nil object to serialize from") 18 | } 19 | 20 | return json.Marshal(obj) 21 | } 22 | 23 | // Unmarshal tries to deserialize input buffer values into input object 24 | func (jm JsonMarshalizer) Unmarshal(obj interface{}, buff []byte) error { 25 | if obj == nil { 26 | return errors.New("nil object to serialize to") 27 | } 28 | if buff == nil { 29 | return errors.New("nil byte buffer to deserialize from") 30 | } 31 | if len(buff) == 0 { 32 | return errors.New("empty byte buffer to deserialize from") 33 | } 34 | 35 | return json.Unmarshal(buff, obj) 36 | } 37 | 38 | // IsInterfaceNil returns true if there is no value under the interface 39 | func (jm *JsonMarshalizer) IsInterfaceNil() bool { 40 | return jm == nil 41 | } 42 | -------------------------------------------------------------------------------- /marshal/gogoProtoMarshalizer.go: -------------------------------------------------------------------------------- 1 | package marshal 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var _ Marshalizer = (*GogoProtoMarshalizer)(nil) 8 | 9 | // GogoProtoMarshalizer implements marshaling with protobuf 10 | type GogoProtoMarshalizer struct { 11 | } 12 | 13 | // Marshal does the actual serialization of an object 14 | // The object to be serialized must implement the gogoProtoObj interface 15 | func (x *GogoProtoMarshalizer) Marshal(obj interface{}) ([]byte, error) { 16 | if msg, ok := obj.(GogoProtoObj); ok { 17 | return msg.Marshal() 18 | } 19 | return nil, fmt.Errorf("%T, %w", obj, ErrMarshallingProto) 20 | } 21 | 22 | // Unmarshal does the actual deserialization of an object 23 | // The object to be deserialized must implement the gogoProtoObj interface 24 | func (x *GogoProtoMarshalizer) Unmarshal(obj interface{}, buff []byte) error { 25 | if msg, ok := obj.(GogoProtoObj); ok { 26 | msg.Reset() 27 | return msg.Unmarshal(buff) 28 | } 29 | 30 | return fmt.Errorf("%T, %w", obj, ErrUnmarshallingProto) 31 | } 32 | 33 | // IsInterfaceNil returns true if there is no value under the interface 34 | func (x *GogoProtoMarshalizer) IsInterfaceNil() bool { 35 | return x == nil 36 | } 37 | -------------------------------------------------------------------------------- /core/export_test.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import "time" 4 | 5 | // GetContainingDuration - 6 | func (sw *StopWatch) GetContainingDuration() (map[string]time.Duration, []string) { 7 | return sw.getContainingDuration() 8 | } 9 | 10 | // GetIdentifiers - 11 | func (sw *StopWatch) GetIdentifiers() []string { 12 | return sw.identifiers 13 | } 14 | 15 | // SetIdentifiers - 16 | func (sw *StopWatch) SetIdentifiers(identifiers []string) { 17 | sw.identifiers = identifiers 18 | } 19 | 20 | // GetStarted - 21 | func (sw *StopWatch) GetStarted(identifier string) (time.Time, bool) { 22 | s, has := sw.started[identifier] 23 | return s, has 24 | } 25 | 26 | // GetElapsed - 27 | func (sw *StopWatch) GetElapsed(identifier string) (time.Duration, bool) { 28 | e, has := sw.elapsed[identifier] 29 | return e, has 30 | } 31 | 32 | // SetElapsed - 33 | func (sw *StopWatch) SetElapsed(identifier string, duration time.Duration) { 34 | sw.elapsed[identifier] = duration 35 | } 36 | 37 | // SplitExponentFraction - 38 | func SplitExponentFraction(val string) (string, string) { 39 | return splitExponentFraction(val) 40 | } 41 | 42 | // TestAutoBalanceDataTriesFlag - 43 | const TestAutoBalanceDataTriesFlag = autoBalanceDataTriesFlag 44 | -------------------------------------------------------------------------------- /data/metrics/metrics.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=. metrics.proto 2 | package metrics 3 | 4 | // ListFromMap returns a list of values from the provided map 5 | func ListFromMap(metricsMap map[string]interface{}) *MetricsList { 6 | r := &MetricsList{ 7 | Metrics: make([]Metric, 0, len(metricsMap)), 8 | } 9 | for key, value := range metricsMap { 10 | m := Metric{ 11 | Key: key, 12 | } 13 | switch v := value.(type) { 14 | case uint64: 15 | m.Value = &Metric_ValUint64{ValUint64: v} 16 | case string: 17 | m.Value = &Metric_ValString{ValString: v} 18 | default: 19 | continue 20 | } 21 | r.Metrics = append(r.Metrics, m) 22 | } 23 | return r 24 | } 25 | 26 | // MapFromList returns a map with the values from the list 27 | func MapFromList(l *MetricsList) map[string]interface{} { 28 | ret := make(map[string]interface{}, len(l.Metrics)) 29 | for _, m := range l.Metrics { 30 | switch v := m.Value.(type) { 31 | case *Metric_ValUint64: 32 | ret[m.Key] = v.ValUint64 33 | case *Metric_ValString: 34 | ret[m.Key] = v.ValString 35 | default: 36 | continue 37 | } 38 | } 39 | return ret 40 | } 41 | -------------------------------------------------------------------------------- /data/typeConverters/uint64ByteSlice/bigEndianConverter.go: -------------------------------------------------------------------------------- 1 | package uint64ByteSlice 2 | 3 | import ( 4 | "encoding/binary" 5 | 6 | "github.com/multiversx/mx-chain-core-go/data/typeConverters" 7 | ) 8 | 9 | type bigEndianConverter struct { 10 | } 11 | 12 | // NewBigEndianConverter creates a big endian uint64-byte slice converter 13 | func NewBigEndianConverter() *bigEndianConverter { 14 | return &bigEndianConverter{} 15 | } 16 | 17 | // ToByteSlice converts uint64 to its byte slice representation 18 | func (*bigEndianConverter) ToByteSlice(value uint64) []byte { 19 | buff := make([]byte, 8) 20 | 21 | binary.BigEndian.PutUint64(buff, value) 22 | 23 | return buff 24 | } 25 | 26 | // ToUint64 converts a byte slice to uint64. Errors if something went wrong 27 | func (*bigEndianConverter) ToUint64(buff []byte) (uint64, error) { 28 | if buff == nil { 29 | return 0, typeConverters.ErrNilByteSlice 30 | } 31 | 32 | if len(buff) != 8 { 33 | return 0, typeConverters.ErrByteSliceLenShouldHaveBeen8 34 | } 35 | 36 | return binary.BigEndian.Uint64(buff), nil 37 | } 38 | 39 | // IsInterfaceNil returns true if there is no value under the interface 40 | func (bec *bigEndianConverter) IsInterfaceNil() bool { 41 | return bec == nil 42 | } 43 | -------------------------------------------------------------------------------- /core/mock/pathManagerStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // PathManagerStub - 8 | type PathManagerStub struct { 9 | PathForEpochCalled func(shardId string, epoch uint32, identifier string) string 10 | PathForStaticCalled func(shardId string, identifier string) string 11 | DatabasePathCalled func() string 12 | } 13 | 14 | // PathForEpoch - 15 | func (p *PathManagerStub) PathForEpoch(shardId string, epoch uint32, identifier string) string { 16 | if p.PathForEpochCalled != nil { 17 | return p.PathForEpochCalled(shardId, epoch, identifier) 18 | } 19 | 20 | return fmt.Sprintf("Epoch_%d/Shard_%s/%s", epoch, shardId, identifier) 21 | } 22 | 23 | // PathForStatic - 24 | func (p *PathManagerStub) PathForStatic(shardId string, identifier string) string { 25 | if p.PathForEpochCalled != nil { 26 | return p.PathForStaticCalled(shardId, identifier) 27 | } 28 | 29 | return fmt.Sprintf("Static/Shard_%s/%s", shardId, identifier) 30 | } 31 | 32 | // DatabasePath - 33 | func (p *PathManagerStub) DatabasePath() string { 34 | if p.DatabasePathCalled != nil { 35 | return p.DatabasePathCalled() 36 | } 37 | 38 | return "db" 39 | } 40 | 41 | // IsInterfaceNil - 42 | func (p *PathManagerStub) IsInterfaceNil() bool { 43 | return p == nil 44 | } 45 | -------------------------------------------------------------------------------- /core/errorHandling.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | ) 7 | 8 | // IsGetNodeFromDBError returns true if the provided error is of type getNodeFromDB 9 | func IsGetNodeFromDBError(err error) bool { 10 | if err == nil { 11 | return false 12 | } 13 | 14 | if IsClosingError(err) { 15 | return false 16 | } 17 | 18 | return strings.Contains(err.Error(), GetNodeFromDBErrorString) 19 | } 20 | 21 | // IsClosingError returns true if the provided error is used whenever the node is in the closing process 22 | func IsClosingError(err error) bool { 23 | if err == nil { 24 | return false 25 | } 26 | 27 | errString := err.Error() 28 | return strings.Contains(errString, ErrDBIsClosed.Error()) || 29 | strings.Contains(errString, ErrContextClosing.Error()) 30 | } 31 | 32 | // UnwrapGetNodeFromDBErr unwraps the provided error until it finds a GetNodeFromDbErrHandler 33 | func UnwrapGetNodeFromDBErr(wrappedErr error) GetNodeFromDbErrHandler { 34 | errWithKeyHandler, ok := wrappedErr.(GetNodeFromDbErrHandler) 35 | for !ok { 36 | if wrappedErr == nil { 37 | return nil 38 | } 39 | 40 | err := errors.Unwrap(wrappedErr) 41 | errWithKeyHandler, ok = err.(GetNodeFromDbErrHandler) 42 | wrappedErr = err 43 | } 44 | 45 | return errWithKeyHandler 46 | } 47 | -------------------------------------------------------------------------------- /.github/workflows/golangci-lint.yml: -------------------------------------------------------------------------------- 1 | name: golangci-lint 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: [ main, feat/*, rc/* ] 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | golangci: 14 | name: golangci linter 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/setup-go@v5 18 | with: 19 | go-version: 1.23.6 20 | - uses: actions/checkout@v4 21 | - name: golangci-lint 22 | uses: golangci/golangci-lint-action@v6 23 | with: 24 | # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. 25 | version: v1.64.5 26 | 27 | # Optional: working directory, useful for monorepos 28 | # working-directory: somedir 29 | 30 | # Optional: golangci-lint command line arguments. 31 | args: --timeout 10m0s --max-issues-per-linter 0 --max-same-issues 0 --print-issued-lines 32 | 33 | # Optional: show only new issues if it's a pull request. The default value is `false`. 34 | only-new-issues: true 35 | 36 | # Optional: if set to true then the action will use pre-installed Go 37 | # skip-go-installation: true 38 | -------------------------------------------------------------------------------- /hashing/fnv/fnv.go: -------------------------------------------------------------------------------- 1 | package fnv 2 | 3 | import ( 4 | fnvLib "hash/fnv" 5 | 6 | "github.com/multiversx/mx-chain-core-go/hashing" 7 | ) 8 | 9 | var _ hashing.Hasher = (*fnv)(nil) 10 | 11 | // fnv is a fnv128a implementation of the hasher interface. 12 | type fnv struct { 13 | emptyHash []byte 14 | } 15 | 16 | // NewFnv initializes the empty hash and returns a new instance of the fnv hasher 17 | func NewFnv() *fnv { 18 | return &fnv{ 19 | emptyHash: computeEmptyHash(), 20 | } 21 | } 22 | 23 | // Compute takes a string, and returns the fnv128a hash of that string 24 | func (f *fnv) Compute(s string) []byte { 25 | if len(s) == 0 { 26 | return f.getEmptyHash() 27 | } 28 | h := fnvLib.New128a() 29 | _, _ = h.Write([]byte(s)) 30 | return h.Sum(nil) 31 | } 32 | 33 | // Size returns the size, in number of bytes, of a fnv128a hash 34 | func (f *fnv) Size() int { 35 | return fnvLib.New128a().Size() 36 | } 37 | 38 | func (f *fnv) getEmptyHash() []byte { 39 | hashCopy := make([]byte, len(f.emptyHash)) 40 | copy(hashCopy, f.emptyHash) 41 | 42 | return hashCopy 43 | } 44 | 45 | func computeEmptyHash() []byte { 46 | h := fnvLib.New128a() 47 | _, _ = h.Write([]byte("")) 48 | return h.Sum(nil) 49 | } 50 | 51 | // IsInterfaceNil returns true if there is no value under the interface 52 | func (f *fnv) IsInterfaceNil() bool { 53 | return f == nil 54 | } 55 | -------------------------------------------------------------------------------- /core/closing/safeChanCloser_test.go: -------------------------------------------------------------------------------- 1 | package closing 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | 8 | "github.com/multiversx/mx-chain-core-go/core/check" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | const timeout = time.Second 13 | 14 | func TestNewSafeChanCloser(t *testing.T) { 15 | t.Parallel() 16 | 17 | closer := NewSafeChanCloser() 18 | assert.False(t, check.IfNil(closer)) 19 | } 20 | 21 | func TestSafeChanCloser_CloseShouldWork(t *testing.T) { 22 | t.Parallel() 23 | 24 | chDone := make(chan struct{}, 1) 25 | closer := NewSafeChanCloser() 26 | go func() { 27 | <-closer.ChanClose() 28 | chDone <- struct{}{} 29 | }() 30 | 31 | closer.Close() 32 | 33 | select { 34 | case <-chDone: 35 | case <-time.After(timeout): 36 | assert.Fail(t, "should have not timed out") 37 | } 38 | } 39 | 40 | func TestSafeChanCloser_CloseConcurrentShouldNotPanic(t *testing.T) { 41 | t.Parallel() 42 | 43 | defer panicHandler(t) 44 | 45 | closer := NewSafeChanCloser() 46 | for i := 0; i < 10; i++ { 47 | go func() { 48 | defer panicHandler(t) 49 | time.Sleep(time.Millisecond * 100) 50 | closer.Close() 51 | }() 52 | } 53 | 54 | time.Sleep(timeout) 55 | } 56 | 57 | func panicHandler(t *testing.T) { 58 | r := recover() 59 | if r != nil { 60 | assert.Fail(t, fmt.Sprintf("should have not paniced: %v", r)) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /core/throttler/numGoRoutinesThrottler.go: -------------------------------------------------------------------------------- 1 | package throttler 2 | 3 | import ( 4 | "sync/atomic" 5 | 6 | "github.com/multiversx/mx-chain-core-go/core" 7 | ) 8 | 9 | // NumGoRoutinesThrottler can limit the number of go routines launched 10 | type NumGoRoutinesThrottler struct { 11 | max int32 12 | counter int32 13 | } 14 | 15 | // NewNumGoRoutinesThrottler creates a new num go routine throttler instance 16 | func NewNumGoRoutinesThrottler(max int32) (*NumGoRoutinesThrottler, error) { 17 | if max <= 0 { 18 | return nil, core.ErrNotPositiveValue 19 | } 20 | 21 | return &NumGoRoutinesThrottler{ 22 | max: max, 23 | }, nil 24 | } 25 | 26 | // CanProcess returns true if current counter is less than max 27 | func (ngrt *NumGoRoutinesThrottler) CanProcess() bool { 28 | valCounter := atomic.LoadInt32(&ngrt.counter) 29 | 30 | return valCounter < ngrt.max 31 | } 32 | 33 | // StartProcessing will increment current counter 34 | func (ngrt *NumGoRoutinesThrottler) StartProcessing() { 35 | atomic.AddInt32(&ngrt.counter, 1) 36 | } 37 | 38 | // EndProcessing will decrement current counter 39 | func (ngrt *NumGoRoutinesThrottler) EndProcessing() { 40 | atomic.AddInt32(&ngrt.counter, -1) 41 | } 42 | 43 | // IsInterfaceNil returns true if there is no value under the interface 44 | func (ngrt *NumGoRoutinesThrottler) IsInterfaceNil() bool { 45 | return ngrt == nil 46 | } 47 | -------------------------------------------------------------------------------- /core/atomic/counter.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import "sync/atomic" 4 | 5 | // Counter is an atomic counter 6 | type Counter struct { 7 | value int64 8 | } 9 | 10 | // Set sets counter 11 | func (counter *Counter) Set(value int64) { 12 | atomic.StoreInt64(&counter.value, value) 13 | } 14 | 15 | // Increment increments counter 16 | func (counter *Counter) Increment() int64 { 17 | return atomic.AddInt64(&counter.value, 1) 18 | } 19 | 20 | // Add adds value to counter 21 | func (counter *Counter) Add(value int64) int64 { 22 | return atomic.AddInt64(&counter.value, value) 23 | } 24 | 25 | // Decrement decrements counter 26 | func (counter *Counter) Decrement() int64 { 27 | return atomic.AddInt64(&counter.value, -1) 28 | } 29 | 30 | // Subtract subtracts value from counter 31 | func (counter *Counter) Subtract(value int64) int64 { 32 | return atomic.AddInt64(&counter.value, -value) 33 | } 34 | 35 | // Get gets counter 36 | func (counter *Counter) Get() int64 { 37 | return atomic.LoadInt64(&counter.value) 38 | } 39 | 40 | // Reset resets counter and returns the previous value 41 | func (counter *Counter) Reset() int64 { 42 | return atomic.SwapInt64(&counter.value, 0) 43 | } 44 | 45 | // GetUint64 gets counter as uint64 46 | func (counter *Counter) GetUint64() uint64 { 47 | value := counter.Get() 48 | if value < 0 { 49 | return 0 50 | } 51 | return uint64(value) 52 | } 53 | -------------------------------------------------------------------------------- /marshal/txJsonMarshalizer.go: -------------------------------------------------------------------------------- 1 | package marshal 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | ) 7 | 8 | // TxJsonMarshalizer represents a custom marshalizer for transactions which does not escape HTML characters in strings 9 | type TxJsonMarshalizer struct { 10 | } 11 | 12 | // Marshal tries to serialize the obj parameter 13 | func (t *TxJsonMarshalizer) Marshal(obj interface{}) ([]byte, error) { 14 | bytesBuffer := new(bytes.Buffer) 15 | jsonEncoder := json.NewEncoder(bytesBuffer) 16 | jsonEncoder.SetEscapeHTML(false) 17 | err := jsonEncoder.Encode(obj) 18 | if err != nil { 19 | return nil, err 20 | } 21 | 22 | encodedResult := bytesBuffer.Bytes() 23 | return trimLineFeed(encodedResult), nil 24 | } 25 | 26 | func trimLineFeed(bytes []byte) []byte { 27 | // this should be replaced, but for some reason, bytes.TrimRight(b, "\r") does not work 28 | lastByte := bytes[len(bytes)-1:] 29 | if lastByte[0] == byte(10) { // hardcoded for now 30 | return bytes[:len(bytes)-1] 31 | } 32 | 33 | return bytes 34 | } 35 | 36 | // Unmarshal tries to deserialize input buffer values into input object 37 | func (t *TxJsonMarshalizer) Unmarshal(obj interface{}, buff []byte) error { 38 | return json.Unmarshal(buff, obj) 39 | } 40 | 41 | // IsInterfaceNil returns true if there is no value under the interface 42 | func (t *TxJsonMarshalizer) IsInterfaceNil() bool { 43 | return t == nil 44 | } 45 | -------------------------------------------------------------------------------- /data/stateChange/accountChanges.go: -------------------------------------------------------------------------------- 1 | package stateChange 2 | 3 | const ( 4 | // NoChange is the default value for account changes 5 | NoChange = uint32(0) 6 | // NonceChanged is the location of the bit that represents the NonceChanged change 7 | NonceChanged = uint32(1) 8 | // BalanceChanged is the location of the bit that represents the BalanceChanged change 9 | BalanceChanged = uint32(2) 10 | // CodeHashChanged is the location of the bit that represents the CodeHashChanged change 11 | CodeHashChanged = uint32(4) 12 | // RootHashChanged is the location of the bit that represents the RootHashChanged change 13 | RootHashChanged = uint32(8) 14 | // DeveloperRewardChanged is the location of the bit that represents the DeveloperRewardChanged change 15 | DeveloperRewardChanged = uint32(16) 16 | // OwnerAddressChanged is the location of the bit that represents the OwnerAddressChanged change 17 | OwnerAddressChanged = uint32(32) 18 | // UserNameChanged is the location of the bit that represents the UserNameChanged change 19 | UserNameChanged = uint32(64) 20 | // CodeMetadataChanged is the location of the bit that represents the CodeMetadataChanged change 21 | CodeMetadataChanged = uint32(128) 22 | ) 23 | 24 | // AddAccountChange adds a change to the current changes and returns the updated changes 25 | func AddAccountChange(changes uint32, change uint32) uint32 { 26 | return changes | change 27 | } 28 | -------------------------------------------------------------------------------- /hashing/sha256/sha256.go: -------------------------------------------------------------------------------- 1 | package sha256 2 | 3 | import ( 4 | sha256Lib "crypto/sha256" 5 | 6 | "github.com/multiversx/mx-chain-core-go/hashing" 7 | ) 8 | 9 | var _ hashing.Hasher = (*sha256)(nil) 10 | 11 | // sha256 is a sha256 implementation of the hasher interface. 12 | type sha256 struct { 13 | emptyHash []byte 14 | } 15 | 16 | // NewSha256 initializes the empty hash and returns a new instance of the sha256 hasher 17 | func NewSha256() *sha256 { 18 | return &sha256{ 19 | emptyHash: computeEmptyHash(), 20 | } 21 | } 22 | 23 | // Compute takes a string, and returns the sha256 hash of that string 24 | func (s *sha256) Compute(str string) []byte { 25 | if len(str) == 0 { 26 | return s.getEmptyHash() 27 | } 28 | h := sha256Lib.New() 29 | _, _ = h.Write([]byte(str)) 30 | return h.Sum(nil) 31 | } 32 | 33 | // Size returns the size, in number of bytes, of a sha256 hash 34 | func (s *sha256) Size() int { 35 | return sha256Lib.Size 36 | } 37 | 38 | func (s *sha256) getEmptyHash() []byte { 39 | hashCopy := make([]byte, len(s.emptyHash)) 40 | copy(hashCopy, s.emptyHash) 41 | 42 | return hashCopy 43 | } 44 | 45 | func computeEmptyHash() []byte { 46 | h := sha256Lib.New() 47 | _, _ = h.Write([]byte("")) 48 | return h.Sum(nil) 49 | } 50 | 51 | // IsInterfaceNil returns true if there is no value under the interface 52 | func (s *sha256) IsInterfaceNil() bool { 53 | return s == nil 54 | } 55 | -------------------------------------------------------------------------------- /core/sync/rwmutex.go: -------------------------------------------------------------------------------- 1 | package sync 2 | 3 | import "sync" 4 | 5 | // rwMutex is a mutex that can be used to lock/unlock a resource 6 | // this component is not concurrent safe, concurrent accesses need to be managed by the caller 7 | type rwMutex struct { 8 | cntLocks int32 9 | cntRLocks int32 10 | 11 | controlMut sync.RWMutex 12 | } 13 | 14 | // newRWMutex returns a new instance of rwMutex 15 | func newRWMutex() *rwMutex { 16 | return &rwMutex{} 17 | } 18 | 19 | func (rm *rwMutex) updateCounterLock() { 20 | rm.cntLocks++ 21 | } 22 | 23 | func (rm *rwMutex) updateCounterRLock() { 24 | rm.cntRLocks++ 25 | } 26 | 27 | func (rm *rwMutex) updateCounterUnlock() { 28 | rm.cntLocks-- 29 | } 30 | 31 | func (rm *rwMutex) updateCounterRUnlock() { 32 | rm.cntRLocks-- 33 | } 34 | 35 | // lock locks the rwMutex 36 | func (rm *rwMutex) lock() { 37 | rm.controlMut.Lock() 38 | } 39 | 40 | // unlock unlocks the rwMutex 41 | func (rm *rwMutex) unlock() { 42 | rm.controlMut.Unlock() 43 | } 44 | 45 | // rLock locks for read the rwMutex 46 | func (rm *rwMutex) rLock() { 47 | rm.controlMut.RLock() 48 | } 49 | 50 | // rUnlock unlocks for read the rwMutex 51 | func (rm *rwMutex) rUnlock() { 52 | rm.controlMut.RUnlock() 53 | } 54 | 55 | // numLocks returns the number of locks on the rwMutex 56 | func (rm *rwMutex) numLocks() int32 { 57 | cntLocks := rm.cntLocks 58 | cntRLocks := rm.cntRLocks 59 | 60 | return cntLocks + cntRLocks 61 | } 62 | -------------------------------------------------------------------------------- /hashing/keccak/keccak.go: -------------------------------------------------------------------------------- 1 | package keccak 2 | 3 | import ( 4 | "github.com/multiversx/mx-chain-core-go/hashing" 5 | "golang.org/x/crypto/sha3" 6 | ) 7 | 8 | var _ hashing.Hasher = (*keccak)(nil) 9 | 10 | // keccak is a sha3-keccak implementation of the hasher interface. 11 | type keccak struct { 12 | emptyHash []byte 13 | } 14 | 15 | // NewKeccak initializes the empty hash and returns a new instance of the keccak hasher 16 | func NewKeccak() *keccak { 17 | return &keccak{ 18 | emptyHash: computeEmptyHash(), 19 | } 20 | } 21 | 22 | // Compute takes a string, and returns the sha3-keccak hash of that string 23 | func (k *keccak) Compute(s string) []byte { 24 | if len(s) == 0 { 25 | return k.getEmptyHash() 26 | } 27 | h := sha3.NewLegacyKeccak256() 28 | _, _ = h.Write([]byte(s)) 29 | return h.Sum(nil) 30 | } 31 | 32 | // Size returns the size, in number of bytes, of a sha3-keccak hash 33 | func (k *keccak) Size() int { 34 | return sha3.NewLegacyKeccak256().Size() 35 | } 36 | 37 | func (k *keccak) getEmptyHash() []byte { 38 | hashCopy := make([]byte, len(k.emptyHash)) 39 | copy(hashCopy, k.emptyHash) 40 | 41 | return hashCopy 42 | } 43 | 44 | func computeEmptyHash() []byte { 45 | h := sha3.NewLegacyKeccak256() 46 | _, _ = h.Write([]byte("")) 47 | return h.Sum(nil) 48 | } 49 | 50 | // IsInterfaceNil returns true if there is no value under the interface 51 | func (k *keccak) IsInterfaceNil() bool { 52 | return k == nil 53 | } 54 | -------------------------------------------------------------------------------- /core/sliceUtil/sliceUtil_test.go: -------------------------------------------------------------------------------- 1 | package sliceUtil_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/multiversx/mx-chain-core-go/core/sliceUtil" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestTrimSliceSliceByte_EmptyInputShouldDoNothing(t *testing.T) { 11 | t.Parallel() 12 | 13 | input := make([][]byte, 0) 14 | res := sliceUtil.TrimSliceSliceByte(input) 15 | 16 | assert.Equal(t, input, res) 17 | } 18 | 19 | func TestTrimSliceSliceByte_ShouldDecreaseCapacity(t *testing.T) { 20 | t.Parallel() 21 | 22 | input := make([][]byte, 0, 5) 23 | input = append(input, []byte("el1")) 24 | input = append(input, []byte("el2")) 25 | 26 | assert.Equal(t, 2, len(input)) 27 | assert.Equal(t, 5, cap(input)) 28 | 29 | // after calling the trim func, the capacity should be equal to the len 30 | 31 | input = sliceUtil.TrimSliceSliceByte(input) 32 | assert.Equal(t, 2, len(input)) 33 | assert.Equal(t, 2, cap(input)) 34 | } 35 | 36 | func TestTrimSliceSliceByte_SliceAlreadyOkShouldDoNothing(t *testing.T) { 37 | t.Parallel() 38 | 39 | input := make([][]byte, 0, 2) 40 | input = append(input, []byte("el1")) 41 | input = append(input, []byte("el2")) 42 | 43 | assert.Equal(t, 2, len(input)) 44 | assert.Equal(t, 2, cap(input)) 45 | 46 | // after calling the trim func, the capacity should be equal to the len 47 | 48 | input = sliceUtil.TrimSliceSliceByte(input) 49 | assert.Equal(t, 2, len(input)) 50 | assert.Equal(t, 2, cap(input)) 51 | } 52 | -------------------------------------------------------------------------------- /core/random/fisherYates_test.go: -------------------------------------------------------------------------------- 1 | package random 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/multiversx/mx-chain-core-go/core/mock" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | // ------- FisherYatesShuffle 11 | 12 | func TestFisherYatesShuffle_EmptyShouldReturnEmpty(t *testing.T) { 13 | indexes := make([]int, 0) 14 | randomizer := &mock.IntRandomizerStub{} 15 | 16 | resultIndexes := FisherYatesShuffle(indexes, randomizer) 17 | 18 | assert.Empty(t, resultIndexes) 19 | } 20 | 21 | func TestFisherYatesShuffle_OneElementShouldReturnTheSame(t *testing.T) { 22 | indexes := []int{1} 23 | randomizer := &mock.IntRandomizerStub{ 24 | IntnCalled: func(n int) int { 25 | return n - 1 26 | }, 27 | } 28 | 29 | resultIndexes := FisherYatesShuffle(indexes, randomizer) 30 | 31 | assert.Equal(t, indexes, resultIndexes) 32 | } 33 | 34 | func TestFisherYatesShuffle_ShouldWork(t *testing.T) { 35 | indexes := []int{1, 2, 3, 4, 5} 36 | randomizer := &mock.IntRandomizerStub{ 37 | IntnCalled: func(n int) int { 38 | return 0 39 | }, 40 | } 41 | 42 | //this will cause a rotation of the first element: 43 | //i = 4: 5, 2, 3, 4, 1 (swap 1 <-> 5) 44 | //i = 3: 4, 2, 3, 5, 1 (swap 5 <-> 4) 45 | //i = 2: 3, 2, 4, 5, 1 (swap 3 <-> 4) 46 | //i = 1: 2, 3, 4, 5, 1 (swap 3 <-> 2) 47 | 48 | resultIndexes := FisherYatesShuffle(indexes, randomizer) 49 | expectedResult := []int{2, 3, 4, 5, 1} 50 | 51 | assert.Equal(t, expectedResult, resultIndexes) 52 | } 53 | -------------------------------------------------------------------------------- /core/mock/marshalizerMock.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | ) 7 | 8 | // ErrMockMarshalizer - 9 | var ErrMockMarshalizer = errors.New("MarshalizerMock generic error") 10 | 11 | // ErrNilObjectToMarshal - 12 | var ErrNilObjectToMarshal = errors.New("nil object to serialize from") 13 | 14 | // MarshalizerMock that will be used for testing 15 | type MarshalizerMock struct { 16 | Fail bool 17 | } 18 | 19 | // Marshal converts the input object in a slice of bytes 20 | func (mm *MarshalizerMock) Marshal(obj interface{}) ([]byte, error) { 21 | if mm.Fail { 22 | return nil, ErrMockMarshalizer 23 | } 24 | 25 | if obj == nil { 26 | return nil, ErrNilObjectToMarshal 27 | } 28 | 29 | return json.Marshal(obj) 30 | } 31 | 32 | // Unmarshal applies the serialized values over an instantiated object 33 | func (mm *MarshalizerMock) Unmarshal(obj interface{}, buff []byte) error { 34 | if mm.Fail { 35 | return ErrMockMarshalizer 36 | } 37 | 38 | if obj == nil { 39 | return errors.New("nil object to serilize to") 40 | } 41 | 42 | if buff == nil { 43 | return errors.New("nil byte buffer to deserialize from") 44 | } 45 | 46 | if len(buff) == 0 { 47 | return errors.New("empty byte buffer to deserialize from") 48 | } 49 | 50 | return json.Unmarshal(buff, obj) 51 | } 52 | 53 | // IsInterfaceNil returns true if there is no value under the interface 54 | func (mm *MarshalizerMock) IsInterfaceNil() bool { 55 | return mm == nil 56 | } 57 | -------------------------------------------------------------------------------- /data/mock/marshalizerMock.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | ) 7 | 8 | var errMockMarshalizer = errors.New("MarshalizerMock generic error") 9 | 10 | // MarshalizerMock that will be used for testing 11 | type MarshalizerMock struct { 12 | Fail bool 13 | } 14 | 15 | // Marshal converts the input object in a slice of bytes 16 | func (mm *MarshalizerMock) Marshal(obj interface{}) ([]byte, error) { 17 | if mm.Fail { 18 | return nil, errMockMarshalizer 19 | } 20 | 21 | if obj == nil { 22 | return nil, errors.New("nil object to serilize from") 23 | } 24 | 25 | return json.Marshal(obj) 26 | } 27 | 28 | // Unmarshal applies the serialized values over an instantiated object 29 | func (mm *MarshalizerMock) Unmarshal(obj interface{}, buff []byte) error { 30 | if mm.Fail { 31 | return errMockMarshalizer 32 | } 33 | 34 | if obj == nil { 35 | return errors.New("nil object to serilize to") 36 | } 37 | 38 | if buff == nil { 39 | return errors.New("nil byte buffer to deserialize from") 40 | } 41 | 42 | if len(buff) == 0 { 43 | return errors.New("empty byte buffer to deserialize from") 44 | } 45 | 46 | return json.Unmarshal(buff, obj) 47 | } 48 | 49 | // Version is deprecated and will be removed 50 | func (*MarshalizerMock) Version() string { 51 | return "JSON/v.0.0.0.1" 52 | } 53 | 54 | // IsInterfaceNil returns true if there is no value under the interface 55 | func (mm *MarshalizerMock) IsInterfaceNil() bool { 56 | return mm == nil 57 | } 58 | -------------------------------------------------------------------------------- /core/check/ifNil_test.go: -------------------------------------------------------------------------------- 1 | package check_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/multiversx/mx-chain-core-go/core/check" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | type testInterfaceNilObj struct { 11 | } 12 | 13 | func (tino *testInterfaceNilObj) IsInterfaceNil() bool { 14 | return tino == nil 15 | } 16 | 17 | func TestCheckIfNil_NilInterfaceShouldRetTrue(t *testing.T) { 18 | t.Parallel() 19 | 20 | assert.True(t, check.IfNil(nil)) 21 | assert.True(t, check.IfNilReflect(nil)) 22 | } 23 | 24 | func TestCheckIfNil_NilUnderlyingLayerShouldRetTrue(t *testing.T) { 25 | t.Parallel() 26 | 27 | var tino *testInterfaceNilObj 28 | 29 | assert.True(t, check.IfNil(tino)) 30 | assert.True(t, check.IfNilReflect(tino)) 31 | } 32 | 33 | func TestCheckIfNil_WithInstanceShouldRetFalse(t *testing.T) { 34 | t.Parallel() 35 | 36 | tino := &testInterfaceNilObj{} 37 | 38 | assert.False(t, check.IfNil(tino)) 39 | assert.False(t, check.IfNilReflect(tino)) 40 | } 41 | 42 | func BenchmarkIfNilChecker(b *testing.B) { 43 | var nr *testInterfaceNilObj 44 | r := testInterfaceNilObj{} 45 | list := []check.NilInterfaceChecker{nil, &r, nr} 46 | 47 | for n := 0; n < b.N; n++ { 48 | for _, i := range list { 49 | check.IfNil(i) 50 | } 51 | } 52 | } 53 | 54 | func BenchmarkCheckIsItfReflect(b *testing.B) { 55 | var ns *struct{} 56 | s := struct{}{} 57 | 58 | list := []interface{}{nil, ns, &s} 59 | for n := 0; n < b.N; n++ { 60 | for _, i := range list { 61 | check.IfNilReflect(i) 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /core/getNodeFromDBErrWithKey.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | ) 7 | 8 | // GetNodeFromDBErrorString represents the string which is returned when a getting node from DB returns an error 9 | const GetNodeFromDBErrorString = "getNodeFromDB error" 10 | 11 | // getNodeFromDBErrWithKey defines a custom error for trie get node 12 | type getNodeFromDBErrWithKey struct { 13 | getErr error 14 | key []byte 15 | dbIdentifier string 16 | } 17 | 18 | // NewGetNodeFromDBErrWithKey will create a new instance of GetNodeFromDBErrWithKey 19 | func NewGetNodeFromDBErrWithKey(key []byte, err error, id string) *getNodeFromDBErrWithKey { 20 | return &getNodeFromDBErrWithKey{ 21 | getErr: err, 22 | key: key, 23 | dbIdentifier: id, 24 | } 25 | } 26 | 27 | // Error returns the error as string 28 | func (e *getNodeFromDBErrWithKey) Error() string { 29 | return fmt.Sprintf( 30 | "%s: %s for key %v", 31 | GetNodeFromDBErrorString, 32 | e.getErr.Error(), 33 | hex.EncodeToString(e.key), 34 | ) 35 | } 36 | 37 | // GetKey will return the key that generated the error 38 | func (e *getNodeFromDBErrWithKey) GetKey() []byte { 39 | return e.key 40 | } 41 | 42 | // GetIdentifier will return the db identifier corresponding to the db 43 | func (e *getNodeFromDBErrWithKey) GetIdentifier() string { 44 | return e.dbIdentifier 45 | } 46 | 47 | // IsInterfaceNil returns true if there is no value under the interface 48 | func (e *getNodeFromDBErrWithKey) IsInterfaceNil() bool { 49 | return e == nil 50 | } 51 | -------------------------------------------------------------------------------- /display/placeholders_test.go: -------------------------------------------------------------------------------- 1 | package display_test 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/multiversx/mx-chain-core-go/display" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | const ( 13 | testMessage = "message to display" 14 | testTimestamp = "2000-01-01 00:00:00" 15 | ) 16 | 17 | func TestHeadline_MessageTooLongItShouldBeReturnedAsItIs(t *testing.T) { 18 | t.Parallel() 19 | 20 | message := "message way too long to be displayed in a single line with the timestamp and delimiter included." 21 | message += "in the moment of writing this test, the line was limited to 100 characters" 22 | delimiter := "." 23 | 24 | res := display.Headline(message, testTimestamp, delimiter) 25 | 26 | assert.Equal(t, message, res) 27 | } 28 | 29 | func TestHeadline_DelimiterTooLongShouldBeTrimmed(t *testing.T) { 30 | t.Parallel() 31 | 32 | firstCharOnDelimiter := "!" 33 | delimiter := firstCharOnDelimiter + "~=" 34 | 35 | res := display.Headline(testMessage, testTimestamp, delimiter) 36 | 37 | assert.False(t, strings.Contains(res, delimiter)) 38 | assert.True(t, strings.Contains(res, firstCharOnDelimiter)) 39 | fmt.Println(res) 40 | } 41 | 42 | func TestHeadline_ResultedStringContainsAllData(t *testing.T) { 43 | t.Parallel() 44 | 45 | delimiter := "." 46 | 47 | res := display.Headline(testMessage, testTimestamp, delimiter) 48 | 49 | assert.True(t, strings.Contains(res, testMessage)) 50 | assert.True(t, strings.Contains(res, testTimestamp)) 51 | assert.True(t, strings.Contains(res, delimiter)) 52 | fmt.Println(res) 53 | } 54 | -------------------------------------------------------------------------------- /core/epochFlags_test.go: -------------------------------------------------------------------------------- 1 | package core_test 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/multiversx/mx-chain-core-go/core" 9 | "github.com/multiversx/mx-chain-core-go/core/mock" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func TestCheckHandlerCompatibility(t *testing.T) { 14 | t.Parallel() 15 | 16 | err := core.CheckHandlerCompatibility(nil, []core.EnableEpochFlag{}) 17 | require.Equal(t, core.ErrNilEnableEpochsHandler, err) 18 | 19 | testFlags := []core.EnableEpochFlag{"f0", "f1", "f2"} 20 | allFlagsDefinedHandler := &mock.EnableEpochsHandlerStub{ 21 | IsFlagDefinedCalled: func(flag core.EnableEpochFlag) bool { 22 | return true 23 | }, 24 | } 25 | err = core.CheckHandlerCompatibility(allFlagsDefinedHandler, testFlags) 26 | require.Nil(t, err) 27 | 28 | allFlagsUndefinedHandler := &mock.EnableEpochsHandlerStub{ 29 | IsFlagDefinedCalled: func(flag core.EnableEpochFlag) bool { 30 | return false 31 | }, 32 | } 33 | err = core.CheckHandlerCompatibility(allFlagsUndefinedHandler, testFlags) 34 | require.True(t, errors.Is(err, core.ErrInvalidEnableEpochsHandler)) 35 | 36 | missingFlag := testFlags[1] 37 | oneFlagUndefinedHandler := &mock.EnableEpochsHandlerStub{ 38 | IsFlagDefinedCalled: func(flag core.EnableEpochFlag) bool { 39 | return flag != missingFlag 40 | }, 41 | } 42 | err = core.CheckHandlerCompatibility(oneFlagUndefinedHandler, testFlags) 43 | require.True(t, errors.Is(err, core.ErrInvalidEnableEpochsHandler)) 44 | require.True(t, strings.Contains(err.Error(), string(missingFlag))) 45 | } 46 | -------------------------------------------------------------------------------- /core/random/concurrentSafeIntRandomizer_test.go: -------------------------------------------------------------------------------- 1 | package random 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestConcurrentSafeIntRandomizer_IntnConcurrent(t *testing.T) { 12 | csir := &ConcurrentSafeIntRandomizer{} 13 | 14 | defer func() { 15 | r := recover() 16 | if r != nil { 17 | assert.Fail(t, fmt.Sprintf("randomizer fail: %v", t)) 18 | } 19 | }() 20 | 21 | maxIterations := 100 22 | for i := 0; i < maxIterations; i++ { 23 | go func(idx int) { 24 | for { 25 | _ = csir.Intn(idx + 1) 26 | time.Sleep(time.Millisecond) 27 | } 28 | }(i) 29 | } 30 | 31 | fmt.Println("Waiting 1 second...") 32 | time.Sleep(time.Second * 1) 33 | } 34 | 35 | func TestConcurrentSafeIntRandomizer_IntnInvalidShouldReturnZero(t *testing.T) { 36 | t.Parallel() 37 | 38 | csir := &ConcurrentSafeIntRandomizer{} 39 | assert.False(t, csir.IsInterfaceNil()) 40 | 41 | res := csir.Intn(-1) 42 | assert.Equal(t, 0, res) 43 | 44 | res = csir.Intn(0) 45 | assert.Equal(t, 0, res) 46 | 47 | res = csir.Intn(1) 48 | assert.Equal(t, 0, res) 49 | } 50 | 51 | func TestConcurrentSafeIntRandomizer_IntnShouldWork(t *testing.T) { 52 | t.Parallel() 53 | 54 | csir := &ConcurrentSafeIntRandomizer{} 55 | assert.False(t, csir.IsInterfaceNil()) 56 | 57 | maxValue := 70 58 | res := csir.Intn(maxValue) 59 | 60 | assert.True(t, res >= 0, fmt.Sprintf("0 comparison, generated %d, max %d", res, maxValue)) 61 | assert.True(t, res < maxValue, fmt.Sprintf("max comparison, generated %d, max %d", res, maxValue)) 62 | } 63 | -------------------------------------------------------------------------------- /core/counting/concurrentShardedCounts_test.go: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func TestConcurrentShardedCounts(t *testing.T) { 12 | counts := NewConcurrentShardedCounts() 13 | counts.PutCounts("foo", 42) 14 | counts.PutCounts("bar", 43) 15 | 16 | total := counts.GetTotal() 17 | asString := counts.String() 18 | 19 | require.Equal(t, int64(85), total) 20 | require.Equal(t, "Total:85; [bar]=43; [foo]=42; ", asString) 21 | } 22 | 23 | func TestConcurrentShardedCounts_ConcurrentReadsAndWrites(t *testing.T) { 24 | counts := NewConcurrentShardedCounts() 25 | var wg sync.WaitGroup 26 | wg.Add(2) 27 | 28 | go func() { 29 | for i := int64(0); i < 100; i++ { 30 | counts.PutCounts("foo", 42) 31 | counts.PutCounts("bar", 43) 32 | } 33 | 34 | wg.Done() 35 | }() 36 | 37 | go func() { 38 | for i := 0; i < 100; i++ { 39 | total := counts.GetTotal() 40 | assert.True(t, total == 0 || total == 42 || total == 43 || total == 85) 41 | } 42 | 43 | wg.Done() 44 | }() 45 | 46 | wg.Wait() 47 | 48 | total := counts.GetTotal() 49 | asString := counts.String() 50 | 51 | require.Equal(t, int64(85), total) 52 | require.Equal(t, "Total:85; [bar]=43; [foo]=42; ", asString) 53 | } 54 | 55 | func TestConcurrentShardedCounts_IsInterfaceNil(t *testing.T) { 56 | counts := NewConcurrentShardedCounts() 57 | require.False(t, counts.IsInterfaceNil()) 58 | 59 | thisIsNil := (*ConcurrentShardedCounts)(nil) 60 | require.True(t, thisIsNil.IsInterfaceNil()) 61 | } 62 | -------------------------------------------------------------------------------- /data/block/metaBlockChecks_test.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/multiversx/mx-chain-core-go/data" 8 | "github.com/stretchr/testify/assert" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | var metablockExceptionFields = []string{ 13 | "ShardInfo", 14 | "PeerInfo", 15 | "EpochStart", 16 | "Signature", 17 | "LeaderSignature", 18 | "PubKeysBitmap", 19 | "ReceiptsHash", 20 | "Reserved", 21 | "PreviousHeaderProof", 22 | } 23 | 24 | func TestMetaBlockHeader_Checks(t *testing.T) { 25 | t.Parallel() 26 | 27 | t.Run("nil pointer receiver", func(t *testing.T) { 28 | t.Parallel() 29 | 30 | var objectToTest *MetaBlock 31 | err := objectToTest.CheckFieldsForNil() 32 | require.NotNil(t, err) 33 | assert.ErrorIs(t, err, data.ErrNilPointerReceiver) 34 | }) 35 | t.Run("test all fields when set", func(t *testing.T) { 36 | t.Parallel() 37 | 38 | objectToTest := &MetaBlock{} 39 | 40 | fields := prepareFieldsList(objectToTest, headerV1ExceptionFields...) 41 | assert.NotEmpty(t, fields) 42 | }) 43 | t.Run("test all fields when one is unset", func(t *testing.T) { 44 | t.Parallel() 45 | 46 | objectToTest := &MetaBlock{} 47 | 48 | fields := prepareFieldsList(objectToTest, metablockExceptionFields...) 49 | assert.NotEmpty(t, fields) 50 | 51 | populateFieldsWithRandomValue(t, objectToTest, fields) 52 | err := objectToTest.CheckFieldsForNil() 53 | require.Nil(t, err) 54 | 55 | fmt.Printf("fields tests on %T\n", objectToTest) 56 | for i := 0; i < len(fields); i++ { 57 | testField(t, objectToTest, fields, i) 58 | } 59 | }) 60 | } 61 | -------------------------------------------------------------------------------- /core/mock/enableEpochsHandlerStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import "github.com/multiversx/mx-chain-core-go/core" 4 | 5 | // EnableEpochsHandlerStub - 6 | type EnableEpochsHandlerStub struct { 7 | IsFlagDefinedCalled func(flag core.EnableEpochFlag) bool 8 | IsFlagEnabledCalled func(flag core.EnableEpochFlag) bool 9 | IsFlagEnabledInEpochCalled func(flag core.EnableEpochFlag, epoch uint32) bool 10 | GetActivationEpochCalled func(flag core.EnableEpochFlag) uint32 11 | } 12 | 13 | // IsFlagDefined - 14 | func (stub *EnableEpochsHandlerStub) IsFlagDefined(flag core.EnableEpochFlag) bool { 15 | if stub.IsFlagDefinedCalled != nil { 16 | return stub.IsFlagDefinedCalled(flag) 17 | } 18 | return false 19 | } 20 | 21 | // IsFlagEnabled - 22 | func (stub *EnableEpochsHandlerStub) IsFlagEnabled(flag core.EnableEpochFlag) bool { 23 | if stub.IsFlagEnabledCalled != nil { 24 | return stub.IsFlagEnabledCalled(flag) 25 | } 26 | return false 27 | } 28 | 29 | // IsFlagEnabledInEpoch - 30 | func (stub *EnableEpochsHandlerStub) IsFlagEnabledInEpoch(flag core.EnableEpochFlag, epoch uint32) bool { 31 | if stub.IsFlagEnabledInEpochCalled != nil { 32 | return stub.IsFlagEnabledInEpochCalled(flag, epoch) 33 | } 34 | return false 35 | } 36 | 37 | // GetActivationEpoch - 38 | func (stub *EnableEpochsHandlerStub) GetActivationEpoch(flag core.EnableEpochFlag) uint32 { 39 | if stub.GetActivationEpochCalled != nil { 40 | return stub.GetActivationEpochCalled(flag) 41 | } 42 | return 0 43 | } 44 | 45 | // IsInterfaceNil - 46 | func (stub *EnableEpochsHandlerStub) IsInterfaceNil() bool { 47 | return stub == nil 48 | } 49 | -------------------------------------------------------------------------------- /core/atomic/flag_test.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestFlag_SetReturningPrevious(t *testing.T) { 11 | t.Parallel() 12 | 13 | var flag Flag 14 | var wg sync.WaitGroup 15 | 16 | require.False(t, flag.IsSet()) 17 | 18 | wg.Add(2) 19 | 20 | go func() { 21 | _ = flag.SetReturningPrevious() 22 | wg.Done() 23 | }() 24 | 25 | go func() { 26 | _ = flag.SetReturningPrevious() 27 | wg.Done() 28 | }() 29 | 30 | wg.Wait() 31 | require.True(t, flag.IsSet()) 32 | } 33 | 34 | func TestFlag_Reset(t *testing.T) { 35 | t.Parallel() 36 | 37 | var flag Flag 38 | var wg sync.WaitGroup 39 | 40 | _ = flag.SetReturningPrevious() 41 | require.True(t, flag.IsSet()) 42 | 43 | wg.Add(2) 44 | 45 | go func() { 46 | flag.Reset() 47 | wg.Done() 48 | }() 49 | 50 | go func() { 51 | flag.Reset() 52 | wg.Done() 53 | }() 54 | 55 | wg.Wait() 56 | require.False(t, flag.IsSet()) 57 | } 58 | 59 | func TestFlag_SetValue(t *testing.T) { 60 | t.Parallel() 61 | 62 | var flag Flag 63 | var wg sync.WaitGroup 64 | 65 | // First, Toggle(true) 66 | wg.Add(2) 67 | 68 | go func() { 69 | flag.SetValue(true) 70 | wg.Done() 71 | }() 72 | 73 | go func() { 74 | flag.SetValue(true) 75 | wg.Done() 76 | }() 77 | 78 | wg.Wait() 79 | require.True(t, flag.IsSet()) 80 | 81 | // Then, Toggle(false) 82 | wg.Add(2) 83 | 84 | go func() { 85 | flag.SetValue(false) 86 | wg.Done() 87 | }() 88 | 89 | go func() { 90 | flag.SetValue(false) 91 | wg.Done() 92 | }() 93 | 94 | wg.Wait() 95 | require.False(t, flag.IsSet()) 96 | } 97 | -------------------------------------------------------------------------------- /marshal/sizeCheckUnmarshalizer.go: -------------------------------------------------------------------------------- 1 | package marshal 2 | 3 | var _ Marshalizer = (*sizeCheckUnmarshalizer)(nil) 4 | 5 | type sizeCheckUnmarshalizer struct { 6 | Marshalizer 7 | acceptedDelta uint32 8 | } 9 | 10 | // NewSizeCheckUnmarshalizer creates a wrapper around an existing marshalizer m 11 | // which, during unmarshaling, also checks that the provided buffer dose not contain 12 | // additional unused data. 13 | func NewSizeCheckUnmarshalizer(m Marshalizer, maxDelta uint32) Marshalizer { 14 | scu := &sizeCheckUnmarshalizer{ 15 | Marshalizer: m, 16 | acceptedDelta: maxDelta, 17 | } 18 | return scu 19 | } 20 | 21 | // Unmarshal tries to unmarshal input buffer values into output object, and checks 22 | // for additional unused data 23 | func (scu *sizeCheckUnmarshalizer) Unmarshal(obj interface{}, buff []byte) error { 24 | err := scu.Marshalizer.Unmarshal(obj, buff) 25 | if err != nil { 26 | return err 27 | } 28 | 29 | var objSize int 30 | result, ok := obj.(Sizer) 31 | if !ok { 32 | out, errMarshal := scu.Marshal(obj) 33 | if errMarshal != nil { 34 | return errMarshal 35 | } 36 | 37 | objSize = len(out) 38 | } else { 39 | objSize = result.Size() 40 | } 41 | 42 | maxSize := objSize + objSize*int(scu.acceptedDelta)/100 43 | if len(buff) > maxSize { 44 | return ErrUnmarshallingBadSize 45 | } 46 | return nil 47 | } 48 | 49 | // IsInterfaceNil returns true if there is no value under the interface or 50 | // target marshalizer 51 | func (scu *sizeCheckUnmarshalizer) IsInterfaceNil() bool { 52 | if scu != nil { 53 | return scu.Marshalizer == nil || scu.Marshalizer.IsInterfaceNil() 54 | } 55 | return true 56 | } 57 | -------------------------------------------------------------------------------- /core/nodetype/nodeTypeProvider_test.go: -------------------------------------------------------------------------------- 1 | package nodetype 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/multiversx/mx-chain-core-go/core" 8 | "github.com/multiversx/mx-chain-core-go/core/check" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestNewNodeTypeProvider(t *testing.T) { 13 | t.Parallel() 14 | 15 | ntp := NewNodeTypeProvider(core.NodeTypeObserver) 16 | require.False(t, check.IfNil(ntp)) 17 | } 18 | 19 | func TestNodeTypeProvider_SetterAndGetterType(t *testing.T) { 20 | t.Parallel() 21 | 22 | ntp := NewNodeTypeProvider(core.NodeTypeObserver) 23 | require.Equal(t, core.NodeTypeObserver, ntp.GetType()) 24 | 25 | ntp.SetType(core.NodeTypeObserver) 26 | require.Equal(t, core.NodeTypeObserver, ntp.GetType()) 27 | 28 | ntp.SetType(core.NodeTypeValidator) 29 | require.Equal(t, core.NodeTypeValidator, ntp.GetType()) 30 | 31 | ntp.SetType(core.NodeTypeObserver) 32 | require.Equal(t, core.NodeTypeObserver, ntp.GetType()) 33 | } 34 | 35 | func TestNodeTypeProvider_ConcurrentSafe(t *testing.T) { 36 | t.Parallel() 37 | 38 | ntp := NewNodeTypeProvider(core.NodeTypeObserver) 39 | 40 | defer func() { 41 | r := recover() 42 | require.Empty(t, r) 43 | }() 44 | 45 | numGoRoutines := 100 46 | 47 | wg := sync.WaitGroup{} 48 | wg.Add(numGoRoutines) 49 | for i := 0; i < numGoRoutines; i++ { 50 | go func(idx int) { 51 | modRes := idx % 3 52 | switch modRes { 53 | case 0: 54 | _ = ntp.GetType() 55 | case 1: 56 | ntp.SetType(core.NodeTypeObserver) 57 | case 2: 58 | ntp.SetType(core.NodeTypeValidator) 59 | } 60 | wg.Done() 61 | }(i) 62 | } 63 | 64 | wg.Wait() 65 | } 66 | -------------------------------------------------------------------------------- /data/block/trigger.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package proto; 4 | 5 | option go_package = "block"; 6 | option (gogoproto.stable_marshaler_all) = true; 7 | 8 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 9 | import "block.proto"; 10 | import "blockV2.proto"; 11 | import "metaBlock.proto"; 12 | 13 | message ShardTriggerRegistry { 14 | bool IsEpochStart = 1; 15 | bool NewEpochHeaderReceived = 2; 16 | uint32 Epoch = 3; 17 | uint32 MetaEpoch = 4; 18 | int64 CurrentRoundIndex = 5; 19 | uint64 EpochStartRound = 6; 20 | uint64 EpochFinalityAttestingRound = 7; 21 | bytes EpochMetaBlockHash = 8; 22 | Header EpochStartShardHeader = 9; 23 | } 24 | 25 | message ShardTriggerRegistryV2 { 26 | HeaderV2 EpochStartShardHeader = 1; 27 | bool IsEpochStart = 2; 28 | bool NewEpochHeaderReceived = 3; 29 | uint32 Epoch = 4; 30 | uint32 MetaEpoch = 5; 31 | int64 CurrentRoundIndex = 6; 32 | uint64 EpochStartRound = 7; 33 | uint64 EpochFinalityAttestingRound = 8; 34 | bytes EpochMetaBlockHash = 9; 35 | } 36 | 37 | message MetaTriggerRegistry { 38 | uint32 Epoch = 1; 39 | uint64 CurrentRound = 2; 40 | uint64 EpochFinalityAttestingRound = 3; 41 | uint64 CurrEpochStartRound = 4; 42 | uint64 PrevEpochStartRound = 5; 43 | bytes EpochStartMetaHash = 6; 44 | MetaBlock EpochStartMeta = 7; 45 | } 46 | -------------------------------------------------------------------------------- /core/getNodeFromDBErrWithKey_test.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "encoding/hex" 5 | "errors" 6 | "fmt" 7 | "testing" 8 | 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | var testErr = errors.New("test error") 13 | var testKey = []byte("test key") 14 | var testId = "test id" 15 | 16 | func TestNewStopWatch(t *testing.T) { 17 | t.Parallel() 18 | 19 | err := NewGetNodeFromDBErrWithKey(testKey, testErr, testId) 20 | assert.Equal(t, testErr, err.getErr) 21 | assert.Equal(t, testKey, err.key) 22 | assert.Equal(t, testId, err.dbIdentifier) 23 | } 24 | 25 | func TestGetNodeFromDBErrWithKey_Error(t *testing.T) { 26 | t.Parallel() 27 | 28 | expectedResult := fmt.Sprintf( 29 | "%s: %s for key %v", 30 | GetNodeFromDBErrorString, 31 | testErr.Error(), 32 | hex.EncodeToString(testKey), 33 | ) 34 | err := NewGetNodeFromDBErrWithKey(testKey, testErr, testId) 35 | assert.Equal(t, expectedResult, err.Error()) 36 | } 37 | 38 | func TestGetNodeFromDBErrWithKey_GetKey(t *testing.T) { 39 | t.Parallel() 40 | 41 | err := NewGetNodeFromDBErrWithKey(testKey, testErr, testId) 42 | assert.Equal(t, testKey, err.GetKey()) 43 | } 44 | 45 | func TestGetNodeFromDBErrWithKey_GetIdentifier(t *testing.T) { 46 | t.Parallel() 47 | 48 | err := NewGetNodeFromDBErrWithKey(testKey, testErr, testId) 49 | assert.Equal(t, testId, err.GetIdentifier()) 50 | } 51 | 52 | func TestGetNodeFromDBErrWithKey_IsInterfaceNil(t *testing.T) { 53 | t.Parallel() 54 | 55 | var err *getNodeFromDBErrWithKey 56 | assert.True(t, err.IsInterfaceNil()) 57 | 58 | err = NewGetNodeFromDBErrWithKey(testKey, testErr, testId) 59 | assert.False(t, err.IsInterfaceNil()) 60 | } 61 | -------------------------------------------------------------------------------- /data/stateChange/stateChange.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package proto; 4 | 5 | option go_package = "github.com/multiversx/mx-chain-core-go/data/stateChange;stateChange"; 6 | option (gogoproto.stable_marshaler_all) = true; 7 | 8 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 9 | 10 | message StateAccesses { 11 | repeated StateAccess StateAccess = 1 [(gogoproto.jsontag) = "stateAccess"]; 12 | } 13 | 14 | enum ActionType { 15 | Read = 0; 16 | Write = 1; 17 | } 18 | 19 | message StateAccess { 20 | ActionType Type = 1 [(gogoproto.jsontag) = "type"]; 21 | int32 Index = 2 [(gogoproto.jsontag) = "index"]; 22 | bytes TxHash = 3 [(gogoproto.jsontag) = "txHash"]; 23 | bytes MainTrieKey = 4 [(gogoproto.jsontag) = "mainTrieKey"]; 24 | bytes MainTrieVal = 5 [(gogoproto.jsontag) = "mainTrieVal"]; 25 | uint32 Operation = 6 [(gogoproto.jsontag) = "operation"]; 26 | repeated DataTrieChange DataTrieChanges = 7 [(gogoproto.jsontag) = "dataTrieChanges,omitempty"]; 27 | uint32 AccountChanges = 8 [(gogoproto.jsontag) = "accountChanges"]; 28 | } 29 | 30 | message DataTrieChange { 31 | ActionType Type = 1 [(gogoproto.jsontag) = "type"]; 32 | bytes Key = 2 [(gogoproto.jsontag) = "key"]; 33 | bytes Val = 3 [(gogoproto.jsontag) = "val"]; 34 | uint32 Version = 4 [(gogoproto.jsontag) = "version"]; 35 | uint32 Operation = 5 [(gogoproto.jsontag) = "operation"]; 36 | } 37 | -------------------------------------------------------------------------------- /data/rewardTx/rewardTx_test.go: -------------------------------------------------------------------------------- 1 | package rewardTx_test 2 | 3 | import ( 4 | "math/big" 5 | "testing" 6 | 7 | "github.com/multiversx/mx-chain-core-go/data" 8 | "github.com/multiversx/mx-chain-core-go/data/rewardTx" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestRewardTx_GettersAndSetters(t *testing.T) { 13 | t.Parallel() 14 | 15 | rwdTx := rewardTx.RewardTx{} 16 | 17 | addr := []byte("address") 18 | value := big.NewInt(37) 19 | 20 | rwdTx.SetRcvAddr(addr) 21 | rwdTx.SetValue(value) 22 | 23 | assert.Equal(t, []byte(nil), rwdTx.GetSndAddr()) 24 | assert.Equal(t, addr, rwdTx.GetRcvAddr()) 25 | assert.Equal(t, value, rwdTx.GetValue()) 26 | assert.Equal(t, []byte(""), rwdTx.GetData()) 27 | assert.Equal(t, uint64(0), rwdTx.GetGasLimit()) 28 | assert.Equal(t, uint64(0), rwdTx.GetGasPrice()) 29 | assert.Equal(t, uint64(0), rwdTx.GetNonce()) 30 | } 31 | 32 | func TestRewardTx_CheckIntegrityShouldWork(t *testing.T) { 33 | t.Parallel() 34 | 35 | rwdTx := &rewardTx.RewardTx{ 36 | Round: 19, 37 | RcvAddr: []byte("rcv-address"), 38 | Value: big.NewInt(10), 39 | } 40 | 41 | err := rwdTx.CheckIntegrity() 42 | assert.Nil(t, err) 43 | } 44 | 45 | func TestRewardTx_CheckIntegrityShouldErr(t *testing.T) { 46 | t.Parallel() 47 | 48 | rwdTx := &rewardTx.RewardTx{ 49 | Round: 19, 50 | } 51 | 52 | err := rwdTx.CheckIntegrity() 53 | assert.Equal(t, data.ErrNilRcvAddr, err) 54 | 55 | rwdTx.RcvAddr = []byte("rcv-address") 56 | 57 | err = rwdTx.CheckIntegrity() 58 | assert.Equal(t, data.ErrNilValue, err) 59 | 60 | rwdTx.Value = big.NewInt(-1) 61 | 62 | err = rwdTx.CheckIntegrity() 63 | assert.Equal(t, data.ErrNegativeValue, err) 64 | } 65 | -------------------------------------------------------------------------------- /data/block/emptyBlockCreatorsContainer.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/multiversx/mx-chain-core-go/core" 7 | "github.com/multiversx/mx-chain-core-go/core/check" 8 | "github.com/multiversx/mx-chain-core-go/data" 9 | ) 10 | 11 | type emptyBlockCreatorsContainer struct { 12 | mut sync.RWMutex 13 | blockCreators map[core.HeaderType]EmptyBlockCreator 14 | } 15 | 16 | // NewEmptyBlockCreatorsContainer creates a new block creators container 17 | func NewEmptyBlockCreatorsContainer() *emptyBlockCreatorsContainer { 18 | return &emptyBlockCreatorsContainer{ 19 | blockCreators: make(map[core.HeaderType]EmptyBlockCreator), 20 | } 21 | } 22 | 23 | // Add will add a new empty block creator 24 | func (container *emptyBlockCreatorsContainer) Add(headerType core.HeaderType, creator EmptyBlockCreator) error { 25 | if check.IfNil(creator) { 26 | return data.ErrNilEmptyBlockCreator 27 | } 28 | 29 | container.mut.Lock() 30 | container.blockCreators[headerType] = creator 31 | container.mut.Unlock() 32 | 33 | return nil 34 | } 35 | 36 | // Get will try to get a new empty block creator. Errors if the empty block creator type is not found 37 | func (container *emptyBlockCreatorsContainer) Get(headerType core.HeaderType) (EmptyBlockCreator, error) { 38 | container.mut.RLock() 39 | creator, ok := container.blockCreators[headerType] 40 | container.mut.RUnlock() 41 | 42 | if !ok { 43 | return nil, data.ErrInvalidHeaderType 44 | } 45 | 46 | return creator, nil 47 | } 48 | 49 | // IsInterfaceNil returns true if there is no value under the interface 50 | func (container *emptyBlockCreatorsContainer) IsInterfaceNil() bool { 51 | return container == nil 52 | } 53 | -------------------------------------------------------------------------------- /data/mock/pubkeyConverterStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import "github.com/multiversx/mx-chain-core-go/core" 4 | 5 | // PubkeyConverterStub - 6 | type PubkeyConverterStub struct { 7 | LenCalled func() int 8 | DecodeCalled func(humanReadable string) ([]byte, error) 9 | EncodeCalled func(pkBytes []byte) (string, error) 10 | EncodeSliceCalled func(pkBytesSlice [][]byte) ([]string, error) 11 | SilentEncodeCalled func(pkBytes []byte, log core.Logger) string 12 | } 13 | 14 | // Len - 15 | func (pcs *PubkeyConverterStub) Len() int { 16 | if pcs.LenCalled != nil { 17 | return pcs.LenCalled() 18 | } 19 | 20 | return 0 21 | } 22 | 23 | // Decode - 24 | func (pcs *PubkeyConverterStub) Decode(humanReadable string) ([]byte, error) { 25 | if pcs.DecodeCalled != nil { 26 | return pcs.DecodeCalled(humanReadable) 27 | } 28 | 29 | return make([]byte, 0), nil 30 | } 31 | 32 | // Encode - 33 | func (pcs *PubkeyConverterStub) Encode(pkBytes []byte) (string, error) { 34 | if pcs.EncodeCalled != nil { 35 | return pcs.EncodeCalled(pkBytes) 36 | } 37 | 38 | return "", nil 39 | } 40 | 41 | // EncodeSlice - 42 | func (pcs *PubkeyConverterStub) EncodeSlice(pkBytesSlice [][]byte) ([]string, error) { 43 | if pcs.EncodeSliceCalled != nil { 44 | return pcs.EncodeSliceCalled(pkBytesSlice) 45 | } 46 | 47 | return make([]string, 0), nil 48 | } 49 | 50 | // SilentEncode - 51 | func (pcs *PubkeyConverterStub) SilentEncode(pkBytes []byte, log core.Logger) string { 52 | if pcs.SilentEncodeCalled != nil { 53 | return pcs.SilentEncodeCalled(pkBytes, log) 54 | } 55 | 56 | return "" 57 | } 58 | 59 | // IsInterfaceNil - 60 | func (pcs *PubkeyConverterStub) IsInterfaceNil() bool { 61 | return pcs == nil 62 | } 63 | -------------------------------------------------------------------------------- /data/receipt/receipt.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=$GOPATH/src receipt.proto 2 | package receipt 3 | 4 | import ( 5 | "math/big" 6 | 7 | "github.com/multiversx/mx-chain-core-go/data" 8 | ) 9 | 10 | var _ = data.TransactionHandler(&Receipt{}) 11 | 12 | // IsInterfaceNil verifies if underlying object is nil 13 | func (rpt *Receipt) IsInterfaceNil() bool { 14 | return rpt == nil 15 | } 16 | 17 | // GetNonce returns the nonce of the receipt 18 | func (rpt *Receipt) GetNonce() uint64 { 19 | return 0 20 | } 21 | 22 | // GetRcvAddr returns the receiver address from the receipt 23 | func (rpt *Receipt) GetRcvAddr() []byte { 24 | return rpt.SndAddr 25 | } 26 | 27 | // GetGasLimit returns the gas limit of the receipt 28 | func (rpt *Receipt) GetGasLimit() uint64 { 29 | return 0 30 | } 31 | 32 | // GetGasPrice returns the gas price of the receipt 33 | func (rpt *Receipt) GetGasPrice() uint64 { 34 | return 0 35 | } 36 | 37 | // SetValue sets the value of the receipt 38 | func (rpt *Receipt) SetValue(value *big.Int) { 39 | rpt.Value = value 40 | } 41 | 42 | // SetData sets the data of the receipt 43 | func (rpt *Receipt) SetData(data []byte) { 44 | rpt.Data = data 45 | } 46 | 47 | // SetRcvAddr sets the receiver address of the receipt 48 | func (rpt *Receipt) SetRcvAddr(_ []byte) { 49 | } 50 | 51 | // SetSndAddr sets the sender address of the receipt 52 | func (rpt *Receipt) SetSndAddr(addr []byte) { 53 | rpt.SndAddr = addr 54 | } 55 | 56 | // GetRcvUserName returns the receiver user name from the receipt 57 | func (_ *Receipt) GetRcvUserName() []byte { 58 | return nil 59 | } 60 | 61 | // CheckIntegrity checks for not nil fields and negative value 62 | func (rpt *Receipt) CheckIntegrity() error { 63 | return nil 64 | } 65 | -------------------------------------------------------------------------------- /marshal/testSizeCheckUnmarshal/testStructs_test.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=. testStruct.proto 2 | 3 | package testSizeCheckUnmarshal 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/multiversx/mx-chain-core-go/marshal" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestUnmarshlizerProtoObj(t *testing.T) { 13 | t.Parallel() 14 | 15 | gm := &marshal.GogoProtoMarshalizer{} 16 | 17 | ts2 := &TestStruct2{ 18 | Field1: 1, 19 | Field2: []byte("field2"), 20 | Field3: []byte("field3"), 21 | } 22 | ts1 := &TestStruct1{} 23 | 24 | marshalizedTs2, _ := gm.Marshal(ts2) 25 | err := gm.Unmarshal(ts1, marshalizedTs2) 26 | assert.Nil(t, err) 27 | } 28 | 29 | func TestSizeUnmarshalizerTestStruct2ToTestStruct1Err(t *testing.T) { 30 | t.Parallel() 31 | 32 | gm := &marshal.GogoProtoMarshalizer{} 33 | sizeCheckMarslalizer := marshal.NewSizeCheckUnmarshalizer(gm, 20) 34 | 35 | ts2 := &TestStruct2{ 36 | Field1: 1, 37 | Field2: []byte("field2"), 38 | Field3: []byte("field3"), 39 | } 40 | ts1 := &TestStruct1{} 41 | 42 | marshalizedTs2, _ := sizeCheckMarslalizer.Marshal(ts2) 43 | err := sizeCheckMarslalizer.Unmarshal(ts1, marshalizedTs2) 44 | assert.Equal(t, marshal.ErrUnmarshallingBadSize, err) 45 | } 46 | 47 | func TestSizeUnmarshalizerTestStruct1ToTestStruct2(t *testing.T) { 48 | t.Parallel() 49 | 50 | gm := &marshal.GogoProtoMarshalizer{} 51 | sizeCheckMarslalizer := marshal.NewSizeCheckUnmarshalizer(gm, 20) 52 | 53 | ts1 := &TestStruct1{ 54 | Field1: 1, 55 | Field2: []byte("filed2"), 56 | } 57 | ts2 := &TestStruct2{} 58 | 59 | marshalizedTs1, _ := sizeCheckMarslalizer.Marshal(ts1) 60 | err := sizeCheckMarslalizer.Unmarshal(ts2, marshalizedTs1) 61 | assert.Nil(t, err) 62 | } 63 | -------------------------------------------------------------------------------- /data/smartContractResult/smartContractResult.proto: -------------------------------------------------------------------------------- 1 | 2 | syntax = "proto3"; 3 | 4 | package proto; 5 | 6 | option go_package = "github.com/multiversx/mx-chain-core-go/data/smartContractResult;smartContractResult"; 7 | option (gogoproto.stable_marshaler_all) = true; 8 | 9 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 10 | 11 | message SmartContractResult { 12 | uint64 Nonce = 1 [(gogoproto.jsontag) = "nonce"]; 13 | bytes Value = 2 [(gogoproto.jsontag) = "value", (gogoproto.casttypewith) = "math/big.Int;github.com/multiversx/mx-chain-core-go/data.BigIntCaster"]; 14 | bytes RcvAddr = 3 [(gogoproto.jsontag) = "receiver"]; 15 | bytes SndAddr = 4 [(gogoproto.jsontag) = "sender"]; 16 | bytes RelayerAddr = 5 [(gogoproto.jsontag) = "relayer"]; 17 | bytes RelayedValue = 6 [(gogoproto.jsontag) = "relayedValue", (gogoproto.casttypewith) = "math/big.Int;github.com/multiversx/mx-chain-core-go/data.BigIntCaster"]; 18 | bytes Code = 7 [(gogoproto.jsontag) = "code,omitempty"]; 19 | bytes Data = 8 [(gogoproto.jsontag) = "data,omitempty"]; 20 | bytes PrevTxHash = 9 [(gogoproto.jsontag) = "prevTxHash"]; 21 | bytes OriginalTxHash = 10 [(gogoproto.jsontag) = "originalTxHash"]; 22 | uint64 GasLimit = 11 [(gogoproto.jsontag) = "gasLimit"]; 23 | uint64 GasPrice = 12 [(gogoproto.jsontag) = "gasPrice"]; 24 | int64 CallType = 13 [(gogoproto.jsontag) = "callType", (gogoproto.casttype) = "github.com/multiversx/mx-chain-core-go/data/vm.CallType"]; 25 | bytes CodeMetadata = 14 [(gogoproto.jsontag) = "codeMetadata,omitempty"]; 26 | bytes ReturnMessage = 15 [(gogoproto.jsontag) = "returnMessage,omitempty"]; 27 | bytes OriginalSender = 16 [(gogoproto.jsontag) = "originalSender,omitempty"]; 28 | } 29 | -------------------------------------------------------------------------------- /core/mock/loggerMock.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import "fmt" 4 | 5 | // LoggerMock - 6 | type LoggerMock struct { 7 | } 8 | 9 | // Trace will print a trace log 10 | func (c LoggerMock) Trace(message string, args ...interface{}) { 11 | fmt.Printf("[TRACE] %s %v\n", message, getPrintableArgs(args)) 12 | } 13 | 14 | // Debug will print a debug log 15 | func (c LoggerMock) Debug(message string, args ...interface{}) { 16 | fmt.Printf("[DEBUG] %s %v\n", message, getPrintableArgs(args)) 17 | } 18 | 19 | // Info will print an info log 20 | func (c LoggerMock) Info(message string, args ...interface{}) { 21 | fmt.Printf("[INFO] %s %v\n", message, getPrintableArgs(args)) 22 | } 23 | 24 | // Warn will print a warn log 25 | func (c LoggerMock) Warn(message string, args ...interface{}) { 26 | fmt.Printf("[WARN] %s %v\n", message, getPrintableArgs(args)) 27 | } 28 | 29 | // Error will print an error log 30 | func (c LoggerMock) Error(message string, args ...interface{}) { 31 | fmt.Printf("[ERROR] %s %v\n", message, getPrintableArgs(args)) 32 | } 33 | 34 | // LogIfError will print an error if it is not nil 35 | func (c LoggerMock) LogIfError(err error, args ...interface{}) { 36 | if err != nil { 37 | fmt.Printf("[ERROR] %s %v\n", err.Error(), getPrintableArgs(args)) 38 | } 39 | } 40 | 41 | func getPrintableArgs(args ...interface{}) string { 42 | if len(args)%2 != 0 { 43 | return fmt.Sprintf("%v", args) 44 | } 45 | 46 | printableArgs := "" 47 | 48 | for idx, arg := range args { 49 | if idx%2 == 0 { 50 | printableArgs += fmt.Sprintf("%s = ", arg) 51 | continue 52 | } 53 | printableArgs += fmt.Sprintf("%v ", arg) 54 | } 55 | 56 | return printableArgs 57 | } 58 | 59 | // IsInterfaceNil returns false as the struct doesn't use pointer receivers 60 | func (c LoggerMock) IsInterfaceNil() bool { 61 | return false 62 | } 63 | -------------------------------------------------------------------------------- /data/validator/validatorStatistics.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package proto; 4 | 5 | option go_package = "validator"; 6 | option (gogoproto.stable_marshaler_all) = true; 7 | 8 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 9 | 10 | // ValidatorStatistics holds information about a validator 11 | message ValidatorStatistics { 12 | float TempRating = 1 [(gogoproto.jsontag) = "tempRating"]; 13 | uint32 NumLeaderSuccess = 2 [(gogoproto.jsontag) = "numLeaderSuccess"]; 14 | uint32 NumLeaderFailure = 3 [(gogoproto.jsontag) = "numLeaderFailure"]; 15 | uint32 NumValidatorSuccess = 4 [(gogoproto.jsontag) = "numValidatorSuccess"]; 16 | uint32 NumValidatorFailure = 5 [(gogoproto.jsontag) = "numValidatorFailure"]; 17 | uint32 NumValidatorIgnoredSignatures = 6 [(gogoproto.jsontag) = "numValidatorIgnoredSignatures"]; 18 | float Rating = 7 [(gogoproto.jsontag) = "rating"]; 19 | float RatingModifier = 8 [(gogoproto.jsontag) = "ratingModifier"]; 20 | uint32 TotalNumLeaderSuccess = 9 [(gogoproto.jsontag) = "totalNumLeaderSuccess"]; 21 | uint32 TotalNumLeaderFailure = 10 [(gogoproto.jsontag) = "totalNumLeaderFailure"]; 22 | uint32 TotalNumValidatorSuccess = 11 [(gogoproto.jsontag) = "totalNumValidatorSuccess"]; 23 | uint32 TotalNumValidatorFailure = 12 [(gogoproto.jsontag) = "totalNumValidatorFailure"]; 24 | uint32 TotalNumValidatorIgnoredSignatures = 13 [(gogoproto.jsontag) = "totalNumValidatorIgnoredSignatures"]; 25 | uint32 ShardId = 14 [(gogoproto.jsontag) = "shardId"]; 26 | string ValidatorStatus = 15 [(gogoproto.jsontag) = "validatorStatus"]; 27 | } 28 | -------------------------------------------------------------------------------- /data/vm/callType.go: -------------------------------------------------------------------------------- 1 | package vm 2 | 3 | // CallType specifies the type of SC invocation (in terms of asynchronicity) 4 | type CallType int 5 | 6 | const ( 7 | // DirectCall means that the call is an explicit SC invocation originating from a user Transaction 8 | DirectCall CallType = iota 9 | 10 | // AsynchronousCall means that the invocation was performed from within 11 | // another SmartContract from another Shard, using asyncCall 12 | AsynchronousCall 13 | 14 | // AsynchronousCallBack means that an AsynchronousCall was performed 15 | // previously, and now the control returns to the caller SmartContract's callBack method 16 | AsynchronousCallBack 17 | 18 | // ESDTTransferAndExecute means that there is a smart contract execution after the ESDT transfer 19 | // this is needed in order to skip the check whether a contract is payable or not 20 | ESDTTransferAndExecute 21 | 22 | // ExecOnDestByCaller means that the call is an invocation of a built in function / smart contract from 23 | // another smart contract but the caller is from the previous caller 24 | ExecOnDestByCaller 25 | ) 26 | 27 | const ( 28 | DirectCallStr = "directCall" 29 | AsynchronousCallStr = "asynchronousCall" 30 | AsynchronousCallBackStr = "asynchronousCallBack" 31 | ESDTTransferAndExecuteStr = "esdtTransferAndExecute" 32 | ExecOnDestByCallerStr = "execOnDestByCaller" 33 | UnknownStr = "unknown" 34 | ) 35 | 36 | func (ct CallType) ToString() string { 37 | switch ct { 38 | case DirectCall: 39 | return DirectCallStr 40 | case AsynchronousCall: 41 | return AsynchronousCallStr 42 | case AsynchronousCallBack: 43 | return AsynchronousCallBackStr 44 | case ESDTTransferAndExecute: 45 | return ESDTTransferAndExecuteStr 46 | case ExecOnDestByCaller: 47 | return ExecOnDestByCallerStr 48 | default: 49 | return UnknownStr 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /data/bigIntCaster.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | ) 7 | 8 | // BigIntCaster handles big int operations 9 | type BigIntCaster struct{} 10 | 11 | // Equal returns true if the provided big ints are equal 12 | func (c *BigIntCaster) Equal(a, b *big.Int) bool { 13 | if a == nil { 14 | return b == nil 15 | } 16 | return a.Cmp(b) == 0 17 | } 18 | 19 | // Size returns the size of a big int 20 | func (c *BigIntCaster) Size(a *big.Int) int { 21 | if a == nil { 22 | return 1 23 | } 24 | if size := len(a.Bytes()); size > 0 { 25 | return size + 1 26 | } 27 | return 2 28 | } 29 | 30 | // MarshalTo marshals the first parameter to the second one 31 | func (c *BigIntCaster) MarshalTo(a *big.Int, buf []byte) (int, error) { 32 | if a == nil { 33 | buf[0] = 0 34 | return 1, nil 35 | } 36 | bytes := a.Bytes() 37 | if len(buf) <= len(bytes) { 38 | return 0, ErrInvalidValue 39 | } 40 | copy(buf[1:], bytes) 41 | if a.Sign() < 0 { 42 | buf[0] = 1 43 | } else { 44 | buf[0] = 0 45 | } 46 | bsize := len(bytes) 47 | if bsize > 0 { 48 | return bsize + 1, nil 49 | } 50 | return 2, nil 51 | } 52 | 53 | // Unmarshal unmarshalls the parameter to a big int 54 | func (c *BigIntCaster) Unmarshal(buf []byte) (*big.Int, error) { 55 | switch len(buf) { 56 | case 0: 57 | return nil, fmt.Errorf("bad input") 58 | case 1: 59 | return nil, nil 60 | case 2: 61 | if buf[1] == 0 { 62 | return big.NewInt(0), nil 63 | } 64 | 65 | } 66 | ret := new(big.Int).SetBytes(buf[1:]) 67 | switch buf[0] { 68 | case 0: 69 | 70 | case 1: 71 | ret = ret.Neg(ret) 72 | default: 73 | return nil, fmt.Errorf("invalid sign byte %x", buf[0]) 74 | } 75 | 76 | return ret, nil 77 | } 78 | 79 | // NewPopulated returns a new instance of a big int, pre-populated with a zero 80 | func (c *BigIntCaster) NewPopulated() *big.Int { 81 | return big.NewInt(0) 82 | } 83 | -------------------------------------------------------------------------------- /core/queue/hashQueue_test.go: -------------------------------------------------------------------------------- 1 | package queue 2 | 3 | import ( 4 | "strconv" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestNewHashQueue(t *testing.T) { 11 | t.Parallel() 12 | 13 | hqSize := uint(5) 14 | hq := NewSliceQueue(hqSize) 15 | assert.Equal(t, hqSize, hq.size) 16 | assert.Equal(t, 0, len(hq.queue)) 17 | } 18 | 19 | func TestSliceQueue_AddToAnZeroSizedQueue(t *testing.T) { 20 | t.Parallel() 21 | 22 | hashToAdd := []byte("hash") 23 | hq := NewSliceQueue(0) 24 | 25 | returnedHash := hq.Add(hashToAdd) 26 | assert.Equal(t, hashToAdd, returnedHash) 27 | assert.Equal(t, 0, len(hq.queue)) 28 | } 29 | 30 | func TestSliceQueue_AddToAFullQueue(t *testing.T) { 31 | t.Parallel() 32 | 33 | hashToAdd := []byte("hash") 34 | expectedHash := []byte("expectedHash") 35 | hqSize := uint(5) 36 | hq := NewSliceQueue(hqSize) 37 | 38 | returnedHash := hq.Add(expectedHash) 39 | assert.Equal(t, 0, len(returnedHash)) 40 | 41 | for i := 0; i < int(hqSize-1); i++ { 42 | returnedHash = hq.Add([]byte(strconv.Itoa(i))) 43 | assert.Equal(t, 0, len(returnedHash)) 44 | } 45 | 46 | assert.Equal(t, int(hq.size), len(hq.queue)) 47 | 48 | returnedHash = hq.Add(hashToAdd) 49 | assert.Equal(t, expectedHash, returnedHash) 50 | assert.Equal(t, hashToAdd, hq.queue[len(hq.queue)-1]) 51 | } 52 | 53 | func TestSliceQueue_AddToPartiallyFilledQueue(t *testing.T) { 54 | t.Parallel() 55 | 56 | hashToAdd := []byte("hash") 57 | hqSize := uint(5) 58 | hq := NewSliceQueue(hqSize) 59 | 60 | numHashesToAdd := 3 61 | for i := 0; i < numHashesToAdd; i++ { 62 | returnedHash := hq.Add([]byte(strconv.Itoa(i))) 63 | assert.Equal(t, 0, len(returnedHash)) 64 | } 65 | 66 | assert.Equal(t, numHashesToAdd, len(hq.queue)) 67 | 68 | returnedHash := hq.Add(hashToAdd) 69 | assert.Equal(t, 0, len(returnedHash)) 70 | assert.Equal(t, numHashesToAdd+1, len(hq.queue)) 71 | } 72 | -------------------------------------------------------------------------------- /data/api/apiHyperBlock.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "github.com/multiversx/mx-chain-core-go/data/transaction" 5 | ) 6 | 7 | // Hyperblock contains all fully executed (both in source and in destination shards) transactions notarized in a given metablock 8 | type Hyperblock struct { 9 | Hash string `json:"hash"` 10 | PrevBlockHash string `json:"prevBlockHash"` 11 | StateRootHash string `json:"stateRootHash"` 12 | Nonce uint64 `json:"nonce"` 13 | Round uint64 `json:"round"` 14 | Epoch uint32 `json:"epoch"` 15 | NumTxs uint32 `json:"numTxs"` 16 | AccumulatedFees string `json:"accumulatedFees,omitempty"` 17 | DeveloperFees string `json:"developerFees,omitempty"` 18 | AccumulatedFeesInEpoch string `json:"accumulatedFeesInEpoch,omitempty"` 19 | DeveloperFeesInEpoch string `json:"developerFeesInEpoch,omitempty"` 20 | Timestamp int64 `json:"timestamp,omitempty"` 21 | TimestampMs int64 `json:"timestampMs,omitempty"` 22 | EpochStartInfo *EpochStartInfo `json:"epochStartInfo,omitempty"` 23 | EpochStartShardsData []*EpochStartShardData `json:"epochStartShardsData,omitempty"` 24 | ShardBlocks []*NotarizedBlock `json:"shardBlocks"` 25 | Transactions []*transaction.ApiTransactionResult `json:"transactions"` 26 | Status string `json:"status,omitempty"` 27 | } 28 | -------------------------------------------------------------------------------- /data/esdt/proto/esdt.proto: -------------------------------------------------------------------------------- 1 | 2 | syntax = "proto3"; 3 | 4 | package protoBuiltInFunctions; 5 | 6 | option go_package = "esdt"; 7 | option (gogoproto.stable_marshaler_all) = true; 8 | 9 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 10 | 11 | // ESDigitalToken holds the data for a electronic standard digital token transaction 12 | message ESDigitalToken { 13 | uint32 Type = 1 [(gogoproto.jsontag) = "Type"]; 14 | bytes Value = 2 [(gogoproto.jsontag) = "Value", (gogoproto.casttypewith) = "math/big.Int;github.com/multiversx/mx-chain-core-go/data.BigIntCaster"]; 15 | bytes Properties = 3 [(gogoproto.jsontag) = "Properties"]; 16 | MetaData TokenMetaData = 4 [(gogoproto.jsontag) = "MetaData"]; 17 | bytes Reserved = 5 [(gogoproto.jsontag) = "Reserved"]; 18 | } 19 | 20 | // ESDTRoles holds the roles for a given token and the given address 21 | message ESDTRoles { 22 | repeated bytes Roles = 1 [(gogoproto.jsontag) = "roles"]; 23 | } 24 | 25 | // MetaData hold the metadata structure for the ESDT token 26 | message MetaData { 27 | uint64 Nonce = 1 [(gogoproto.jsontag) = "Nonce"]; 28 | bytes Name = 2 [(gogoproto.jsontag) = "Name"]; 29 | bytes Creator = 3 [(gogoproto.jsontag) = "Creator"]; 30 | uint32 Royalties = 4 [(gogoproto.jsontag) = "Royalties"]; 31 | bytes Hash = 5 [(gogoproto.jsontag) = "Hash"]; 32 | repeated bytes URIs = 6 [(gogoproto.jsontag) = "URIs"]; 33 | bytes Attributes = 7 [(gogoproto.jsontag) = "Attributes"]; 34 | } 35 | 36 | message MetaDataVersion { 37 | uint64 Name = 1 [(gogoproto.jsontag) = "Name"]; 38 | uint64 Creator = 2 [(gogoproto.jsontag) = "Creator"]; 39 | uint64 Royalties = 3 [(gogoproto.jsontag) = "Royalties"]; 40 | uint64 Hash = 4 [(gogoproto.jsontag) = "Hash"]; 41 | uint64 URIs = 5 [(gogoproto.jsontag) = "URIs"]; 42 | uint64 Attributes = 6 [(gogoproto.jsontag) = "Attributes"]; 43 | } 44 | -------------------------------------------------------------------------------- /marshal/gogoProtoMarshalizer_test.go: -------------------------------------------------------------------------------- 1 | package marshal_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/multiversx/mx-chain-core-go/data/block" 8 | "github.com/multiversx/mx-chain-core-go/marshal" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | var miniblock = &block.MiniBlock{} 13 | var gogoMarsh = marshal.GogoProtoMarshalizer{} 14 | 15 | func recovedMarshal(obj interface{}) (buf []byte, err error) { 16 | defer func() { 17 | if p := recover(); p != nil { 18 | if panicError, ok := p.(error); ok { 19 | err = panicError 20 | } else { 21 | err = fmt.Errorf("%#v", p) 22 | } 23 | buf = nil 24 | } 25 | }() 26 | buf, err = gogoMarsh.Marshal(obj) 27 | return 28 | } 29 | 30 | func recovedUnmarshal(obj interface{}, buf []byte) (err error) { 31 | defer func() { 32 | if p := recover(); p != nil { 33 | if panicError, ok := p.(error); ok { 34 | err = panicError 35 | } else { 36 | err = fmt.Errorf("%#v", p) 37 | } 38 | } 39 | }() 40 | err = gogoMarsh.Unmarshal(obj, buf) 41 | return 42 | } 43 | 44 | func TestGogoProtoMarshalizer_Marshal(t *testing.T) { 45 | encNode, err := recovedMarshal(miniblock) 46 | assert.Nil(t, err) 47 | assert.NotNil(t, encNode) 48 | } 49 | 50 | func TestGogoProtoMarshalizer_MarshalWrongObj(t *testing.T) { 51 | 52 | obj := "multiversx" 53 | encNode, err := recovedMarshal(obj) 54 | assert.Nil(t, encNode) 55 | assert.NotNil(t, err) 56 | } 57 | 58 | func TestGogoProtoMarshalizer_Unmarshal(t *testing.T) { 59 | encNode, _ := gogoMarsh.Marshal(miniblock) 60 | newNode := &block.MiniBlock{} 61 | 62 | err := recovedUnmarshal(newNode, encNode) 63 | assert.Nil(t, err) 64 | assert.Equal(t, miniblock, newNode) 65 | } 66 | 67 | func TestGogoProtoMarshalizer_UnmarshalWrongObj(t *testing.T) { 68 | encNode, _ := gogoMarsh.Marshal(miniblock) 69 | err := recovedUnmarshal([]byte{}, encNode) 70 | assert.NotNil(t, err) 71 | } 72 | -------------------------------------------------------------------------------- /core/counting/concurrentShardedCountsWithSize_test.go: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/multiversx/mx-chain-core-go/core" 8 | "github.com/stretchr/testify/assert" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestConcurrentShardedCountsWithSize(t *testing.T) { 13 | counts := NewConcurrentShardedCountsWithSize() 14 | counts.PutCounts("foo", 42, core.MegabyteSize) 15 | counts.PutCounts("bar", 43, core.MegabyteSize*3) 16 | 17 | total := counts.GetTotal() 18 | asString := counts.String() 19 | 20 | require.Equal(t, int64(85), total) 21 | require.Equal(t, "Total:85 (4.00 MB); [bar]=43 (3.00 MB); [foo]=42 (1.00 MB); ", asString) 22 | } 23 | 24 | func TestConcurrentShardedCountsWithSize_ConcurrentReadsAndWrites(t *testing.T) { 25 | counts := NewConcurrentShardedCountsWithSize() 26 | var wg sync.WaitGroup 27 | wg.Add(2) 28 | 29 | go func() { 30 | for i := int64(0); i < 100; i++ { 31 | counts.PutCounts("foo", 42, 128) 32 | counts.PutCounts("bar", 43, 128) 33 | } 34 | 35 | wg.Done() 36 | }() 37 | 38 | go func() { 39 | for i := 0; i < 100; i++ { 40 | total := counts.GetTotal() 41 | totalSize := counts.GetTotalSize() 42 | assert.True(t, total == 0 || total == 42 || total == 43 || total == 85) 43 | assert.True(t, totalSize == 0 || totalSize == 128 || totalSize == 256) 44 | } 45 | 46 | wg.Done() 47 | }() 48 | 49 | wg.Wait() 50 | 51 | require.Equal(t, int64(85), counts.GetTotal()) 52 | require.Equal(t, int64(256), counts.GetTotalSize()) 53 | require.Equal(t, "Total:85 (256 B); [bar]=43 (128 B); [foo]=42 (128 B); ", counts.String()) 54 | } 55 | 56 | func TestConcurrentShardedCountsWithSize_IsInterfaceNil(t *testing.T) { 57 | counts := NewConcurrentShardedCountsWithSize() 58 | require.False(t, counts.IsInterfaceNil()) 59 | 60 | thisIsNil := (*ConcurrentShardedCountsWithSize)(nil) 61 | require.True(t, thisIsNil.IsInterfaceNil()) 62 | } 63 | -------------------------------------------------------------------------------- /data/outport/outportBlock.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src/github.com/multiversx/mx-chain-core-go/data/block -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=$GOPATH/src outportBlock.proto 2 | 3 | package outport 4 | 5 | import ( 6 | "github.com/multiversx/mx-chain-core-go/data" 7 | "github.com/multiversx/mx-chain-core-go/data/block" 8 | ) 9 | 10 | // OutportBlockWithHeader will extend the OutportBlock structure 11 | type OutportBlockWithHeader struct { 12 | *OutportBlock 13 | Header data.HeaderHandler 14 | } 15 | 16 | // HeaderDataWithBody holds header and body data 17 | type HeaderDataWithBody struct { 18 | Body data.BodyHandler 19 | Header data.HeaderHandler 20 | IntraShardMiniBlocks []*block.MiniBlock 21 | HeaderHash []byte 22 | HeaderProof data.HeaderProofHandler 23 | } 24 | 25 | // OutportBlockWithHeaderAndBody is a wrapper for OutportBlock used for outport handler 26 | type OutportBlockWithHeaderAndBody struct { 27 | *OutportBlock 28 | HeaderDataWithBody *HeaderDataWithBody 29 | } 30 | 31 | // SetExecutionOrder sets execution order 32 | func (t *TxInfo) SetExecutionOrder(order uint32) { 33 | t.ExecutionOrder = order 34 | } 35 | 36 | // GetTxHandler returns tx handler 37 | func (t *TxInfo) GetTxHandler() data.TransactionHandler { 38 | return t.Transaction 39 | } 40 | 41 | // SetExecutionOrder sets execution order 42 | func (s *SCRInfo) SetExecutionOrder(order uint32) { 43 | s.ExecutionOrder = order 44 | } 45 | 46 | // GetTxHandler returns tx handler 47 | func (s *SCRInfo) GetTxHandler() data.TransactionHandler { 48 | return s.SmartContractResult 49 | } 50 | 51 | // SetExecutionOrder sets execution order 52 | func (r *RewardInfo) SetExecutionOrder(order uint32) { 53 | r.ExecutionOrder = order 54 | } 55 | 56 | // GetTxHandler returns tx handler 57 | func (r *RewardInfo) GetTxHandler() data.TransactionHandler { 58 | return r.Reward 59 | } 60 | -------------------------------------------------------------------------------- /core/counting/concurrentShardedCounts.go: -------------------------------------------------------------------------------- 1 | package counting 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | "strings" 7 | "sync" 8 | ) 9 | 10 | var _ Counts = (*ConcurrentShardedCounts)(nil) 11 | 12 | // ConcurrentShardedCounts keeps counts for a sharded data structure 13 | // This implementation is concurrently safe 14 | type ConcurrentShardedCounts struct { 15 | mutex sync.RWMutex 16 | byShard map[string]int64 17 | } 18 | 19 | // NewConcurrentShardedCounts creates a new ConcurrentShardedCounts 20 | func NewConcurrentShardedCounts() *ConcurrentShardedCounts { 21 | return &ConcurrentShardedCounts{ 22 | byShard: make(map[string]int64), 23 | } 24 | } 25 | 26 | // PutCounts registers counts for a shard 27 | func (counts *ConcurrentShardedCounts) PutCounts(shardName string, value int64) { 28 | counts.mutex.Lock() 29 | counts.byShard[shardName] = value 30 | counts.mutex.Unlock() 31 | } 32 | 33 | // GetTotal gets total count 34 | func (counts *ConcurrentShardedCounts) GetTotal() int64 { 35 | counts.mutex.RLock() 36 | defer counts.mutex.RUnlock() 37 | 38 | total := int64(0) 39 | for _, count := range counts.byShard { 40 | total += count 41 | } 42 | 43 | return total 44 | } 45 | 46 | func (counts *ConcurrentShardedCounts) String() string { 47 | var builder strings.Builder 48 | 49 | _, _ = fmt.Fprintf(&builder, "Total:%d; ", counts.GetTotal()) 50 | 51 | counts.mutex.RLock() 52 | defer counts.mutex.RUnlock() 53 | 54 | // First, we sort the keys alphanumerically 55 | keys := make([]string, 0, len(counts.byShard)) 56 | for key := range counts.byShard { 57 | keys = append(keys, key) 58 | } 59 | sort.Strings(keys) 60 | 61 | for _, key := range keys { 62 | _, _ = fmt.Fprintf(&builder, "[%s]=%d; ", key, counts.byShard[key]) 63 | } 64 | 65 | return builder.String() 66 | } 67 | 68 | // IsInterfaceNil returns true if there is no value under the interface 69 | func (counts *ConcurrentShardedCounts) IsInterfaceNil() bool { 70 | return counts == nil 71 | } 72 | -------------------------------------------------------------------------------- /data/block/blockV2.proto: -------------------------------------------------------------------------------- 1 | // This file holds the data structures related with the functionality of a shard block V2 2 | syntax = "proto3"; 3 | 4 | package proto; 5 | 6 | option go_package = "block"; 7 | option (gogoproto.stable_marshaler_all) = true; 8 | 9 | import "github.com/gogo/protobuf/gogoproto/gogo.proto"; 10 | import "block.proto"; 11 | 12 | // HeaderV2 extends the Header structure with extra fields for version 2 13 | message HeaderV2 { 14 | Header Header = 1 [(gogoproto.jsontag) = "header,omitempty"]; 15 | bytes ScheduledRootHash = 2 [(gogoproto.jsontag) = "scheduledRootHash,omitempty"]; 16 | bytes ScheduledAccumulatedFees = 3 [(gogoproto.jsontag) = "scheduledAccumulatedFees,omitempty", (gogoproto.casttypewith) = "math/big.Int;github.com/multiversx/mx-chain-core-go/data.BigIntCaster"]; 17 | bytes ScheduledDeveloperFees = 4 [(gogoproto.jsontag) = "scheduledDeveloperFees,omitempty", (gogoproto.casttypewith) = "math/big.Int;github.com/multiversx/mx-chain-core-go/data.BigIntCaster"]; 18 | uint64 ScheduledGasProvided = 5 [(gogoproto.jsontag) = "scheduledGasProvided"]; 19 | uint64 ScheduledGasPenalized = 6 [(gogoproto.jsontag) = "scheduledGasPenalized"]; 20 | uint64 ScheduledGasRefunded = 7 [(gogoproto.jsontag) = "scheduledGasRefunded"]; 21 | } 22 | 23 | message MiniBlockReserved { 24 | ProcessingType ExecutionType = 1 [(gogoproto.jsontag) = "executionType"]; 25 | bytes TransactionsType = 2 [(gogoproto.jsontag) = "transactionsType"]; 26 | } 27 | 28 | message MiniBlockHeaderReserved { 29 | ProcessingType ExecutionType = 1 [(gogoproto.jsontag) = "executionType"]; 30 | MiniBlockState State = 2 [(gogoproto.jsontag) = "state"]; 31 | int32 IndexOfFirstTxProcessed = 3 [(gogoproto.jsontag) = "indexOfFirstTxProcessed"]; 32 | int32 IndexOfLastTxProcessed = 4 [(gogoproto.jsontag) = "indexOfLastTxProcessed"]; 33 | } 34 | -------------------------------------------------------------------------------- /core/mock/appStatusHandlerStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // AppStatusHandlerStub is a stub implementation of AppStatusHandler 4 | type AppStatusHandlerStub struct { 5 | AddUint64Handler func(key string, value uint64) 6 | IncrementHandler func(key string) 7 | DecrementHandler func(key string) 8 | SetUInt64ValueHandler func(key string, value uint64) 9 | SetInt64ValueHandler func(key string, value int64) 10 | SetStringValueHandler func(key string, value string) 11 | CloseHandler func() 12 | } 13 | 14 | // IsInterfaceNil - 15 | func (ashs *AppStatusHandlerStub) IsInterfaceNil() bool { 16 | return ashs == nil 17 | } 18 | 19 | // AddUint64 will call the handler of the stub for incrementing 20 | func (ashs *AppStatusHandlerStub) AddUint64(key string, value uint64) { 21 | ashs.AddUint64Handler(key, value) 22 | } 23 | 24 | // Increment will call the handler of the stub for incrementing 25 | func (ashs *AppStatusHandlerStub) Increment(key string) { 26 | ashs.IncrementHandler(key) 27 | } 28 | 29 | // Decrement will call the handler of the stub for decrementing 30 | func (ashs *AppStatusHandlerStub) Decrement(key string) { 31 | ashs.DecrementHandler(key) 32 | } 33 | 34 | // SetInt64Value will call the handler of the stub for setting an int64 value 35 | func (ashs *AppStatusHandlerStub) SetInt64Value(key string, value int64) { 36 | ashs.SetInt64ValueHandler(key, value) 37 | } 38 | 39 | // SetUInt64Value will call the handler of the stub for setting an uint64 value 40 | func (ashs *AppStatusHandlerStub) SetUInt64Value(key string, value uint64) { 41 | ashs.SetUInt64ValueHandler(key, value) 42 | } 43 | 44 | // SetStringValue will call the handler of the stub for setting an string value 45 | func (ashs *AppStatusHandlerStub) SetStringValue(key string, value string) { 46 | ashs.SetStringValueHandler(key, value) 47 | } 48 | 49 | // Close will call the handler of the stub for closing 50 | func (ashs *AppStatusHandlerStub) Close() { 51 | ashs.CloseHandler() 52 | } 53 | -------------------------------------------------------------------------------- /hashing/blake2b/blake2b_test.go: -------------------------------------------------------------------------------- 1 | package blake2b_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/multiversx/mx-chain-core-go/hashing/blake2b" 7 | "github.com/stretchr/testify/assert" 8 | "github.com/stretchr/testify/require" 9 | blake2bLib "golang.org/x/crypto/blake2b" 10 | ) 11 | 12 | func TestNewBlake2bWithSizeInvalidSizeShouldErr(t *testing.T) { 13 | t.Parallel() 14 | 15 | h, err := blake2b.NewBlake2bWithSize(-2) 16 | require.Nil(t, h) 17 | require.Equal(t, blake2b.ErrInvalidHashSize, err) 18 | } 19 | 20 | func TestBlake2b_ComputeWithDifferentHashSizes(t *testing.T) { 21 | t.Parallel() 22 | 23 | input := "dummy string" 24 | sizes := []int{2, 5, 8, 16, 32, 37, 64} 25 | for _, size := range sizes { 26 | testComputeOk(t, input, size) 27 | } 28 | } 29 | 30 | func testComputeOk(t *testing.T, input string, size int) { 31 | hasher, err := blake2b.NewBlake2bWithSize(size) 32 | require.NoError(t, err) 33 | res := hasher.Compute(input) 34 | assert.Equal(t, size, len(res)) 35 | } 36 | 37 | func TestBlake2b_Empty(t *testing.T) { 38 | 39 | hasher, err := blake2b.NewBlake2bWithSize(64) 40 | require.NoError(t, err) 41 | 42 | var nilStr string 43 | resNil := hasher.Compute(nilStr) 44 | assert.Equal(t, 64, len(resNil)) 45 | 46 | resEmpty := hasher.Compute("") 47 | assert.Equal(t, 64, len(resEmpty)) 48 | 49 | assert.Equal(t, resEmpty, resNil) 50 | 51 | // force recompute 52 | hasher, _ = blake2b.NewBlake2bWithSize(64) 53 | 54 | resEmpty = hasher.Compute("") 55 | assert.Equal(t, 64, len(resEmpty)) 56 | 57 | resEmpty = hasher.Compute("") 58 | assert.Equal(t, 64, len(resEmpty)) 59 | 60 | assert.Equal(t, resEmpty, resNil) 61 | } 62 | 63 | func TestBlake2b_Size(t *testing.T) { 64 | t.Parallel() 65 | 66 | h1 := blake2b.NewBlake2b() 67 | require.Equal(t, blake2bLib.Size256, h1.Size()) 68 | 69 | customSize := 37 70 | h2, err := blake2b.NewBlake2bWithSize(customSize) 71 | require.NoError(t, err) 72 | require.Equal(t, customSize, h2.Size()) 73 | } 74 | -------------------------------------------------------------------------------- /data/esdt/common_test.go: -------------------------------------------------------------------------------- 1 | package esdt 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func TestIsValidPrefixedToken(t *testing.T) { 10 | prefix, valid := IsValidPrefixedToken("sov1-TKN-c0ffee") 11 | require.True(t, valid) 12 | require.Equal(t, "sov1", prefix) 13 | 14 | prefix, valid = IsValidPrefixedToken("sOv1-TKN-c0ffee") 15 | require.False(t, valid) 16 | require.Equal(t, "", prefix) 17 | 18 | prefix, valid = IsValidPrefixedToken("sov1-TkN-c0ffee") 19 | require.False(t, valid) 20 | require.Equal(t, "", prefix) 21 | 22 | prefix, valid = IsValidPrefixedToken("sov1-TKN-c0ffe") 23 | require.False(t, valid) 24 | require.Equal(t, "", prefix) 25 | 26 | prefix, valid = IsValidPrefixedToken("sov1-TKN") 27 | require.False(t, valid) 28 | require.Equal(t, "", prefix) 29 | 30 | prefix, valid = IsValidPrefixedToken("TKN-c0ffee") 31 | require.False(t, valid) 32 | require.Equal(t, "", prefix) 33 | } 34 | 35 | func TestIsValidTokenPrefix(t *testing.T) { 36 | require.False(t, IsValidTokenPrefix("")) 37 | require.False(t, IsValidTokenPrefix("-")) 38 | require.False(t, IsValidTokenPrefix("prefix")) 39 | require.False(t, IsValidTokenPrefix("prefi")) 40 | require.False(t, IsValidTokenPrefix("Prfx")) 41 | require.False(t, IsValidTokenPrefix("pX4")) 42 | require.False(t, IsValidTokenPrefix("px-4")) 43 | 44 | require.True(t, IsValidTokenPrefix("pref")) 45 | require.True(t, IsValidTokenPrefix("sv1")) 46 | } 47 | 48 | func TestIsTickerValid(t *testing.T) { 49 | require.False(t, IsTickerValid("TK")) 50 | require.False(t, IsTickerValid("TKn")) 51 | require.False(t, IsTickerValid("T0KEN-")) 52 | 53 | require.True(t, IsTickerValid("T0KEN")) 54 | } 55 | 56 | func TestIsTokenTickerLenCorrect(t *testing.T) { 57 | require.False(t, IsTokenTickerLenCorrect(len("TOKENALICEALICE"))) 58 | require.False(t, IsTokenTickerLenCorrect(len("AL"))) 59 | 60 | require.True(t, IsTokenTickerLenCorrect(len("ALC"))) 61 | require.True(t, IsTokenTickerLenCorrect(len("ALICE"))) 62 | } 63 | -------------------------------------------------------------------------------- /data/block/epochStartHandler.go: -------------------------------------------------------------------------------- 1 | package block 2 | 3 | import ( 4 | "github.com/multiversx/mx-chain-core-go/data" 5 | ) 6 | 7 | // GetLastFinalizedHeaderHandlers returns the last finalized header handlers 8 | func (es *EpochStart) GetLastFinalizedHeaderHandlers() []data.EpochStartShardDataHandler { 9 | if es == nil { 10 | return nil 11 | } 12 | 13 | epochStartShardDataHandlers := make([]data.EpochStartShardDataHandler, len(es.LastFinalizedHeaders)) 14 | for i := range es.LastFinalizedHeaders { 15 | epochStartShardDataHandlers[i] = &es.LastFinalizedHeaders[i] 16 | } 17 | 18 | return epochStartShardDataHandlers 19 | } 20 | 21 | // GetEconomicsHandler returns the economics handler 22 | func (es *EpochStart) GetEconomicsHandler() data.EconomicsHandler { 23 | if es == nil { 24 | return nil 25 | } 26 | 27 | return &es.Economics 28 | } 29 | 30 | // SetLastFinalizedHeaders sets the last finalized header 31 | func (es *EpochStart) SetLastFinalizedHeaders(epochStartDataHandlers []data.EpochStartShardDataHandler) error { 32 | if es == nil { 33 | return data.ErrNilPointerReceiver 34 | } 35 | 36 | epochStartData := make([]EpochStartShardData, len(epochStartDataHandlers)) 37 | for i := range epochStartDataHandlers { 38 | shardData, ok := epochStartDataHandlers[i].(*EpochStartShardData) 39 | if !ok { 40 | return data.ErrInvalidTypeAssertion 41 | } 42 | if shardData == nil { 43 | return data.ErrNilPointerDereference 44 | } 45 | epochStartData[i] = *shardData 46 | } 47 | 48 | es.LastFinalizedHeaders = epochStartData 49 | 50 | return nil 51 | } 52 | 53 | // SetEconomics sets the economics data 54 | func (es *EpochStart) SetEconomics(economicsHandler data.EconomicsHandler) error { 55 | if es == nil { 56 | return data.ErrNilPointerReceiver 57 | } 58 | 59 | ec, ok := economicsHandler.(*Economics) 60 | if !ok { 61 | return data.ErrInvalidTypeAssertion 62 | } 63 | if ec == nil { 64 | return data.ErrNilPointerDereference 65 | } 66 | 67 | es.Economics = *ec 68 | 69 | return nil 70 | } 71 | -------------------------------------------------------------------------------- /core/atomic/counter_test.go: -------------------------------------------------------------------------------- 1 | package atomic 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func TestCounter_IncrementAndDecrement(t *testing.T) { 11 | var counter Counter 12 | var wg sync.WaitGroup 13 | 14 | // Increment 100 * 100 times 15 | // Decrement 100 * 50 times 16 | for i := 0; i < 100; i++ { 17 | wg.Add(2) 18 | 19 | go func() { 20 | for j := 0; j < 100; j++ { 21 | counter.Increment() 22 | } 23 | 24 | wg.Done() 25 | }() 26 | 27 | go func() { 28 | for j := 0; j < 50; j++ { 29 | counter.Decrement() 30 | } 31 | 32 | wg.Done() 33 | }() 34 | } 35 | 36 | wg.Wait() 37 | 38 | require.Equal(t, int64(5000), counter.Get()) 39 | require.Equal(t, uint64(5000), counter.GetUint64()) 40 | } 41 | 42 | func TestCounter_AddAndSubtract(t *testing.T) { 43 | var counter Counter 44 | var wg sync.WaitGroup 45 | 46 | wg.Add(2) 47 | 48 | go func() { 49 | for j := 0; j < 10; j++ { 50 | counter.Add(5) 51 | } 52 | 53 | wg.Done() 54 | }() 55 | 56 | go func() { 57 | for j := 0; j < 10; j++ { 58 | counter.Subtract(4) 59 | } 60 | 61 | wg.Done() 62 | }() 63 | 64 | wg.Wait() 65 | 66 | require.Equal(t, int64(10), counter.Get()) 67 | require.Equal(t, uint64(10), counter.GetUint64()) 68 | } 69 | 70 | func TestCounter_SetAndReset(t *testing.T) { 71 | var counter Counter 72 | var wg sync.WaitGroup 73 | 74 | counter.Set(41) 75 | 76 | wg.Add(2) 77 | 78 | go func() { 79 | counter.Set(42) 80 | wg.Done() 81 | }() 82 | 83 | go func() { 84 | counter.Reset() 85 | wg.Done() 86 | }() 87 | 88 | wg.Wait() 89 | 90 | require.True(t, counter.Get() == 0 || counter.Get() == 42) 91 | } 92 | 93 | func TestCounter_GetUint64(t *testing.T) { 94 | var counter Counter 95 | 96 | counter.Set(12345) 97 | require.Equal(t, int64(12345), counter.Get()) 98 | 99 | counter.Set(-42) 100 | require.Equal(t, uint64(0), counter.GetUint64()) 101 | } 102 | -------------------------------------------------------------------------------- /data/vm/vmOutputApi_test.go: -------------------------------------------------------------------------------- 1 | package vm 2 | 3 | import ( 4 | "encoding/hex" 5 | "math/big" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func TestVMOutputApi_GetFirstReturnDataAsBigInt(t *testing.T) { 12 | t.Parallel() 13 | 14 | expectedRes := 37 15 | 16 | vmOutputApi := VMOutputApi{ 17 | ReturnData: [][]byte{big.NewInt(int64(expectedRes)).Bytes()}, 18 | } 19 | 20 | res, err := vmOutputApi.GetFirstReturnData(AsBigInt) 21 | require.NoError(t, err) 22 | 23 | resBigInt, ok := res.(*big.Int) 24 | require.True(t, ok) 25 | require.Equal(t, uint64(expectedRes), resBigInt.Uint64()) 26 | } 27 | 28 | func TestVMOutputApi_GetFirstReturnDataAsBigIntString(t *testing.T) { 29 | t.Parallel() 30 | 31 | expectedRes := "37" 32 | 33 | bi, _ := big.NewInt(0).SetString(expectedRes, 10) 34 | vmOutputApi := VMOutputApi{ 35 | ReturnData: [][]byte{bi.Bytes()}, 36 | } 37 | 38 | res, err := vmOutputApi.GetFirstReturnData(AsBigIntString) 39 | require.NoError(t, err) 40 | 41 | resBigIntString, ok := res.(string) 42 | require.True(t, ok) 43 | require.Equal(t, expectedRes, resBigIntString) 44 | } 45 | 46 | func TestVMOutputApi_GetFirstReturnDataAsHex(t *testing.T) { 47 | t.Parallel() 48 | 49 | expectedRes := hex.EncodeToString([]byte("37")) 50 | 51 | resBytes, _ := hex.DecodeString(expectedRes) 52 | vmOutputApi := VMOutputApi{ 53 | ReturnData: [][]byte{resBytes}, 54 | } 55 | 56 | res, err := vmOutputApi.GetFirstReturnData(AsHex) 57 | require.NoError(t, err) 58 | 59 | resHexString, ok := res.(string) 60 | require.True(t, ok) 61 | require.Equal(t, expectedRes, resHexString) 62 | } 63 | 64 | func TestVMOutputApi_GetFirstReturnDataAsString(t *testing.T) { 65 | t.Parallel() 66 | 67 | expectedRes := "37" 68 | vmOutputApi := VMOutputApi{ 69 | ReturnData: [][]byte{[]byte(expectedRes)}, 70 | } 71 | 72 | res, err := vmOutputApi.GetFirstReturnData(AsString) 73 | require.NoError(t, err) 74 | 75 | resString, ok := res.(string) 76 | require.True(t, ok) 77 | require.Equal(t, expectedRes, resString) 78 | } 79 | -------------------------------------------------------------------------------- /core/versioning/txVersionChecker_test.go: -------------------------------------------------------------------------------- 1 | package versioning 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/multiversx/mx-chain-core-go/core" 7 | "github.com/multiversx/mx-chain-core-go/data/transaction" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func TestTxVersionChecker_IsSignedWithHashOptionsZeroShouldReturnFalse(t *testing.T) { 12 | t.Parallel() 13 | 14 | minTxVersion := uint32(1) 15 | tx := &transaction.Transaction{ 16 | Options: 0, 17 | Version: minTxVersion, 18 | } 19 | tvc := NewTxVersionChecker(minTxVersion) 20 | 21 | res := tvc.IsSignedWithHash(tx) 22 | require.False(t, res) 23 | } 24 | 25 | func TestTxVersionChecker_IsSignedWithHash(t *testing.T) { 26 | t.Parallel() 27 | 28 | minTxVersion := uint32(1) 29 | tx := &transaction.Transaction{ 30 | Options: transaction.MaskSignedWithHash, 31 | Version: minTxVersion + 1, 32 | } 33 | tvc := NewTxVersionChecker(minTxVersion) 34 | 35 | res := tvc.IsSignedWithHash(tx) 36 | require.True(t, res) 37 | } 38 | 39 | func TestTxVersionChecker_IsGuardedTransaction(t *testing.T) { 40 | t.Parallel() 41 | 42 | minTxVersion := uint32(1) 43 | tx := &transaction.Transaction{ 44 | Options: transaction.MaskGuardedTransaction, 45 | Version: minTxVersion+1, 46 | } 47 | 48 | tvc := NewTxVersionChecker(minTxVersion) 49 | res := tvc.IsGuardedTransaction(tx) 50 | require.True(t, res) 51 | 52 | tx.Options = 0 53 | res = tvc.IsGuardedTransaction(tx) 54 | require.False(t, res) 55 | } 56 | 57 | func TestTxVersionChecker_CheckTxVersionShouldReturnErrorOptionsNotZero(t *testing.T) { 58 | minTxVersion := uint32(1) 59 | tx := &transaction.Transaction{ 60 | Options: transaction.MaskSignedWithHash, 61 | Version: minTxVersion, 62 | } 63 | 64 | tvc := NewTxVersionChecker(minTxVersion) 65 | err := tvc.CheckTxVersion(tx) 66 | require.Equal(t, core.ErrInvalidTransactionVersion, err) 67 | } 68 | 69 | func TestTxVersionChecker_CheckTxVersionShould(t *testing.T) { 70 | minTxVersion := uint32(1) 71 | tx := &transaction.Transaction{ 72 | Options: 0, 73 | Version: minTxVersion, 74 | } 75 | 76 | tvc := NewTxVersionChecker(minTxVersion) 77 | err := tvc.CheckTxVersion(tx) 78 | require.Nil(t, err) 79 | } 80 | -------------------------------------------------------------------------------- /core/container/mutexMap.go: -------------------------------------------------------------------------------- 1 | package container 2 | 3 | import "sync" 4 | 5 | // MutexMap represents a concurrent safe map 6 | type MutexMap struct { 7 | mut sync.RWMutex 8 | values map[interface{}]interface{} 9 | } 10 | 11 | // NewMutexMap returns a new instance of a mutex map 12 | func NewMutexMap() *MutexMap { 13 | return &MutexMap{ 14 | values: make(map[interface{}]interface{}), 15 | } 16 | } 17 | 18 | // Get returns the element stored with provided key 19 | func (mm *MutexMap) Get(key interface{}) (interface{}, bool) { 20 | mm.mut.RLock() 21 | val, ok := mm.values[key] 22 | mm.mut.RUnlock() 23 | 24 | return val, ok 25 | } 26 | 27 | // Insert adds the (key, val) tuple if the key does not exist 28 | // returns true operation succeeded 29 | func (mm *MutexMap) Insert(key interface{}, val interface{}) bool { 30 | mm.mut.Lock() 31 | 32 | _, ok := mm.values[key] 33 | if !ok { 34 | mm.values[key] = val 35 | } 36 | 37 | mm.mut.Unlock() 38 | 39 | return !ok 40 | } 41 | 42 | // Set stores the (key, val) tuple, rewriting data if existing 43 | func (mm *MutexMap) Set(key interface{}, val interface{}) { 44 | mm.mut.Lock() 45 | mm.values[key] = val 46 | mm.mut.Unlock() 47 | } 48 | 49 | // Remove deletes a (key, val) tuple (if exists) 50 | func (mm *MutexMap) Remove(key interface{}) { 51 | mm.mut.Lock() 52 | delete(mm.values, key) 53 | mm.mut.Unlock() 54 | } 55 | 56 | // Len returns the inner map size 57 | func (mm *MutexMap) Len() int { 58 | mm.mut.RLock() 59 | defer mm.mut.RUnlock() 60 | 61 | return len(mm.values) 62 | } 63 | 64 | // Keys returns all stored keys. The order is not guaranteed 65 | func (mm *MutexMap) Keys() []interface{} { 66 | mm.mut.RLock() 67 | keys := make([]interface{}, 0, len(mm.values)) 68 | for k := range mm.values { 69 | keys = append(keys, k) 70 | } 71 | mm.mut.RUnlock() 72 | 73 | return keys 74 | } 75 | 76 | // Values returns all stored values. The order is not guaranteed 77 | func (mm *MutexMap) Values() []interface{} { 78 | mm.mut.RLock() 79 | values := make([]interface{}, 0, len(mm.values)) 80 | for _, value := range mm.values { 81 | values = append(values, value) 82 | } 83 | mm.mut.RUnlock() 84 | 85 | return values 86 | } 87 | -------------------------------------------------------------------------------- /data/smartContractResult/smartContractResult.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=$GOPATH/src smartContractResult.proto 2 | package smartContractResult 3 | 4 | import ( 5 | "math/big" 6 | 7 | "github.com/multiversx/mx-chain-core-go/data" 8 | ) 9 | 10 | var _ = data.TransactionHandler(&SmartContractResult{}) 11 | 12 | // IsInterfaceNil verifies if underlying object is nil 13 | func (scr *SmartContractResult) IsInterfaceNil() bool { 14 | return scr == nil 15 | } 16 | 17 | // SetValue sets the value of the smart contract result 18 | func (scr *SmartContractResult) SetValue(value *big.Int) { 19 | scr.Value = value 20 | } 21 | 22 | // SetData sets the data of the smart contract result 23 | func (scr *SmartContractResult) SetData(data []byte) { 24 | scr.Data = data 25 | } 26 | 27 | // SetRcvAddr sets the receiver address of the smart contract result 28 | func (scr *SmartContractResult) SetRcvAddr(addr []byte) { 29 | scr.RcvAddr = addr 30 | } 31 | 32 | // SetSndAddr sets the sender address of the smart contract result 33 | func (scr *SmartContractResult) SetSndAddr(addr []byte) { 34 | scr.SndAddr = addr 35 | } 36 | 37 | // GetRcvUserName returns the receiver user name from the smart contract result 38 | func (_ *SmartContractResult) GetRcvUserName() []byte { 39 | return nil 40 | } 41 | 42 | // TrimSlicePtr creates a copy of the provided slice without the excess capacity 43 | func TrimSlicePtr(in []*SmartContractResult) []*SmartContractResult { 44 | if len(in) == 0 { 45 | return []*SmartContractResult{} 46 | } 47 | ret := make([]*SmartContractResult, len(in)) 48 | copy(ret, in) 49 | return ret 50 | } 51 | 52 | // CheckIntegrity checks for not nil fields and negative value 53 | func (scr *SmartContractResult) CheckIntegrity() error { 54 | if len(scr.RcvAddr) == 0 { 55 | return data.ErrNilRcvAddr 56 | } 57 | if len(scr.SndAddr) == 0 { 58 | return data.ErrNilSndAddr 59 | } 60 | if scr.Value == nil { 61 | return data.ErrNilValue 62 | } 63 | if scr.Value.Sign() < 0 { 64 | return data.ErrNegativeValue 65 | } 66 | if len(scr.PrevTxHash) == 0 { 67 | return data.ErrNilTxHash 68 | } 69 | 70 | return nil 71 | } 72 | -------------------------------------------------------------------------------- /data/rewardTx/rewardTx.go: -------------------------------------------------------------------------------- 1 | //go:generate protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/multiversx/protobuf/protobuf --gogoslick_out=$GOPATH/src rewardTx.proto 2 | package rewardTx 3 | 4 | import ( 5 | "math/big" 6 | 7 | "github.com/multiversx/mx-chain-core-go/data" 8 | ) 9 | 10 | var _ = data.TransactionHandler(&RewardTx{}) 11 | 12 | // IsInterfaceNil verifies if underlying object is nil 13 | func (rtx *RewardTx) IsInterfaceNil() bool { 14 | return rtx == nil 15 | } 16 | 17 | // SetValue sets the value of the transaction 18 | func (rtx *RewardTx) SetValue(value *big.Int) { 19 | rtx.Value = value 20 | } 21 | 22 | // GetNonce returns 0 as reward transactions do not have a nonce 23 | func (rtx *RewardTx) GetNonce() uint64 { 24 | return 0 25 | } 26 | 27 | // GetData returns the data of the reward transaction 28 | func (rtx *RewardTx) GetData() []byte { 29 | return []byte("") 30 | } 31 | 32 | // GetSndAddr returns the sender address from the reward transaction 33 | func (rtx *RewardTx) GetSndAddr() []byte { 34 | return nil 35 | } 36 | 37 | // GetGasLimit returns the gas limit of the smart reward transaction 38 | func (rtx *RewardTx) GetGasLimit() uint64 { 39 | return 0 40 | } 41 | 42 | // GetGasPrice returns the gas price of the smart reward transaction 43 | func (rtx *RewardTx) GetGasPrice() uint64 { 44 | return 0 45 | } 46 | 47 | // SetData sets the data of the reward transaction 48 | func (rtx *RewardTx) SetData(_ []byte) { 49 | } 50 | 51 | // SetRcvAddr sets the receiver address of the reward transaction 52 | func (rtx *RewardTx) SetRcvAddr(addr []byte) { 53 | rtx.RcvAddr = addr 54 | } 55 | 56 | // SetSndAddr sets the sender address of the reward transaction 57 | func (rtx *RewardTx) SetSndAddr(_ []byte) { 58 | } 59 | 60 | // GetRcvUserName returns the receiver user name from the reward transaction 61 | func (rtx *RewardTx) GetRcvUserName() []byte { 62 | return nil 63 | } 64 | 65 | // CheckIntegrity checks for not nil fields and negative value 66 | func (rtx *RewardTx) CheckIntegrity() error { 67 | if len(rtx.RcvAddr) == 0 { 68 | return data.ErrNilRcvAddr 69 | } 70 | if rtx.Value == nil { 71 | return data.ErrNilValue 72 | } 73 | if rtx.Value.Sign() < 0 { 74 | return data.ErrNegativeValue 75 | } 76 | 77 | return nil 78 | } 79 | -------------------------------------------------------------------------------- /core/appStatusPolling/appStatusPolling.go: -------------------------------------------------------------------------------- 1 | package appStatusPolling 2 | 3 | import ( 4 | "context" 5 | "sync" 6 | "time" 7 | 8 | "github.com/multiversx/mx-chain-core-go/core" 9 | "github.com/multiversx/mx-chain-core-go/core/check" 10 | ) 11 | 12 | const minPollingDuration = time.Second 13 | 14 | // AppStatusPolling will update an AppStatusHandler by polling components at a predefined interval 15 | type AppStatusPolling struct { 16 | pollingDuration time.Duration 17 | mutRegisteredFunc sync.RWMutex 18 | registeredFunctions []func(appStatusHandler core.AppStatusHandler) 19 | appStatusHandler core.AppStatusHandler 20 | log core.Logger 21 | } 22 | 23 | // NewAppStatusPolling will return an instance of AppStatusPolling 24 | func NewAppStatusPolling(appStatusHandler core.AppStatusHandler, pollingDuration time.Duration, logger core.Logger) (*AppStatusPolling, error) { 25 | if check.IfNil(appStatusHandler) { 26 | return nil, ErrNilAppStatusHandler 27 | } 28 | if pollingDuration < minPollingDuration { 29 | return nil, ErrPollingDurationToSmall 30 | } 31 | if check.IfNil(logger) { 32 | return nil, core.ErrNilLogger 33 | } 34 | return &AppStatusPolling{ 35 | pollingDuration: pollingDuration, 36 | appStatusHandler: appStatusHandler, 37 | log: logger, 38 | }, nil 39 | } 40 | 41 | // RegisterPollingFunc will register a new handler function 42 | func (asp *AppStatusPolling) RegisterPollingFunc(handler func(appStatusHandler core.AppStatusHandler)) error { 43 | if handler == nil { 44 | return ErrNilHandlerFunc 45 | } 46 | asp.mutRegisteredFunc.Lock() 47 | asp.registeredFunctions = append(asp.registeredFunctions, handler) 48 | asp.mutRegisteredFunc.Unlock() 49 | return nil 50 | } 51 | 52 | // Poll will notify the AppStatusHandler at a given time 53 | func (asp *AppStatusPolling) Poll(ctx context.Context) { 54 | go func() { 55 | for { 56 | select { 57 | case <-ctx.Done(): 58 | asp.log.Debug("closing AppStatusPolling.Poll go routine") 59 | return 60 | case <-time.After(asp.pollingDuration): 61 | } 62 | 63 | asp.mutRegisteredFunc.RLock() 64 | for _, handler := range asp.registeredFunctions { 65 | handler(asp.appStatusHandler) 66 | } 67 | asp.mutRegisteredFunc.RUnlock() 68 | } 69 | }() 70 | } 71 | -------------------------------------------------------------------------------- /core/versioning/versionComparator.go: -------------------------------------------------------------------------------- 1 | package versioning 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/multiversx/mx-chain-core-go/core" 8 | ) 9 | 10 | const numComponents = 3 11 | 12 | type versionComparator struct { 13 | version string 14 | major string 15 | minor string 16 | release string 17 | } 18 | 19 | // NewVersionComparator returns a new version comparator instance 20 | func NewVersionComparator(providedVersion string) (*versionComparator, error) { 21 | vc := &versionComparator{ 22 | version: providedVersion, 23 | } 24 | 25 | var err error 26 | vc.major, vc.minor, vc.release, err = vc.splitVersionComponents(providedVersion) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | return vc, nil 32 | } 33 | 34 | func (vc *versionComparator) splitVersionComponents(version string) (string, string, string, error) { 35 | components := strings.Split(version, ".") 36 | if len(components) != numComponents { 37 | return "", "", "", fmt.Errorf("%w, expected %d, got %d", 38 | core.ErrVersionNumComponents, 39 | numComponents, 40 | len(components), 41 | ) 42 | } 43 | 44 | return components[0], components[1], components[2], nil 45 | } 46 | 47 | // Check compares if the provided value is compatible with the stored values. The comparison is done on all 3 components: 48 | // major, minor and release. A wildcard in any of the components will accept any string 49 | func (vc *versionComparator) Check(version string) error { 50 | major, minor, release, err := vc.splitVersionComponents(version) 51 | if err != nil { 52 | return err 53 | } 54 | 55 | if major != vc.major && vc.major != "*" { 56 | return fmt.Errorf("%w, expected version %s, got %s", core.ErrMajorVersionMismatch, vc.version, version) 57 | } 58 | if minor != vc.minor && vc.minor != "*" { 59 | return fmt.Errorf("%w, expected version %s, got %s", core.ErrMinorVersionMismatch, vc.version, version) 60 | } 61 | if release != vc.release && vc.release != "*" { 62 | return fmt.Errorf("%w, expected version %s, got %s", core.ErrReleaseVersionMismatch, vc.version, version) 63 | } 64 | 65 | return nil 66 | } 67 | 68 | // IsInterfaceNil returns true if there is no value under the interface 69 | func (vc *versionComparator) IsInterfaceNil() bool { 70 | return vc == nil 71 | } 72 | -------------------------------------------------------------------------------- /data/mock/appStatusHandlerStub.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | // AppStatusHandlerStub is a stub implementation of AppStatusHandler 4 | type AppStatusHandlerStub struct { 5 | AddUint64Handler func(key string, value uint64) 6 | IncrementHandler func(key string) 7 | DecrementHandler func(key string) 8 | SetUInt64ValueHandler func(key string, value uint64) 9 | SetInt64ValueHandler func(key string, value int64) 10 | SetStringValueHandler func(key string, value string) 11 | CloseHandler func() 12 | } 13 | 14 | // IsInterfaceNil - 15 | func (ashs *AppStatusHandlerStub) IsInterfaceNil() bool { 16 | return ashs == nil 17 | } 18 | 19 | // AddUint64 will call the handler of the stub for incrementing 20 | func (ashs *AppStatusHandlerStub) AddUint64(key string, value uint64) { 21 | if ashs.AddUint64Handler != nil { 22 | ashs.AddUint64Handler(key, value) 23 | } 24 | } 25 | 26 | // Increment will call the handler of the stub for incrementing 27 | func (ashs *AppStatusHandlerStub) Increment(key string) { 28 | if ashs.IncrementHandler != nil { 29 | ashs.IncrementHandler(key) 30 | } 31 | } 32 | 33 | // Decrement will call the handler of the stub for decrementing 34 | func (ashs *AppStatusHandlerStub) Decrement(key string) { 35 | if ashs.DecrementHandler != nil { 36 | ashs.DecrementHandler(key) 37 | } 38 | } 39 | 40 | // SetInt64Value will call the handler of the stub for setting an int64 value 41 | func (ashs *AppStatusHandlerStub) SetInt64Value(key string, value int64) { 42 | if ashs.SetInt64ValueHandler != nil { 43 | ashs.SetInt64ValueHandler(key, value) 44 | } 45 | } 46 | 47 | // SetUInt64Value will call the handler of the stub for setting an uint64 value 48 | func (ashs *AppStatusHandlerStub) SetUInt64Value(key string, value uint64) { 49 | if ashs.SetUInt64ValueHandler != nil { 50 | ashs.SetUInt64ValueHandler(key, value) 51 | } 52 | } 53 | 54 | // SetStringValue will call the handler of the stub for setting an string value 55 | func (ashs *AppStatusHandlerStub) SetStringValue(key string, value string) { 56 | if ashs.SetStringValueHandler != nil { 57 | ashs.SetStringValueHandler(key, value) 58 | } 59 | } 60 | 61 | // Close will call the handler of the stub for closing 62 | func (ashs *AppStatusHandlerStub) Close() { 63 | if ashs.CloseHandler != nil { 64 | ashs.CloseHandler() 65 | } 66 | } 67 | --------------------------------------------------------------------------------