2022-07-21 13:21:44 +00:00
package rpcsrv
2018-03-23 20:36:59 +00:00
import (
2021-08-05 14:56:17 +00:00
"bytes"
2018-03-23 20:36:59 +00:00
"context"
2020-09-28 11:58:04 +00:00
"crypto/elliptic"
2020-06-04 08:59:22 +00:00
"encoding/binary"
2021-11-17 20:04:50 +00:00
"encoding/hex"
2020-01-14 12:02:38 +00:00
"encoding/json"
2020-08-06 14:44:08 +00:00
"errors"
2018-03-23 20:36:59 +00:00
"fmt"
2020-03-05 12:39:53 +00:00
"math"
2020-07-09 09:57:24 +00:00
"math/big"
2020-03-10 11:56:18 +00:00
"net"
2018-03-23 20:36:59 +00:00
"net/http"
2019-01-25 11:20:35 +00:00
"strconv"
2022-03-21 20:36:19 +00:00
"strings"
2020-05-10 22:00:19 +00:00
"sync"
2023-10-11 10:24:16 +00:00
"sync/atomic"
2020-04-29 12:25:58 +00:00
"time"
2018-03-23 20:36:59 +00:00
2022-07-07 19:03:11 +00:00
"github.com/google/uuid"
2020-04-29 12:25:58 +00:00
"github.com/gorilla/websocket"
2022-07-22 16:17:48 +00:00
"github.com/nspcc-dev/neo-go/pkg/config"
2022-07-08 16:51:59 +00:00
"github.com/nspcc-dev/neo-go/pkg/config/limits"
2020-06-18 09:00:51 +00:00
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
2020-03-03 14:21:42 +00:00
"github.com/nspcc-dev/neo-go/pkg/core"
2020-03-02 17:01:32 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/block"
2022-04-07 15:13:08 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/interop"
2021-11-17 20:04:50 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/interop/iterator"
2022-07-22 19:52:58 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
2021-05-28 11:55:06 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/mempoolevent"
2020-06-05 08:51:39 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/mpt"
2021-10-07 09:03:37 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/native"
2020-03-03 14:21:42 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/state"
2022-07-08 20:25:22 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/storage"
2020-03-03 14:21:42 +00:00
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
2020-09-28 11:58:04 +00:00
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
2020-03-05 14:48:30 +00:00
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
2020-03-03 14:21:42 +00:00
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/io"
2022-07-22 16:09:29 +00:00
"github.com/nspcc-dev/neo-go/pkg/neorpc"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
2022-10-17 10:31:24 +00:00
"github.com/nspcc-dev/neo-go/pkg/neorpc/rpcevent"
2020-03-03 14:21:42 +00:00
"github.com/nspcc-dev/neo-go/pkg/network"
2021-02-05 07:26:23 +00:00
"github.com/nspcc-dev/neo-go/pkg/network/payload"
2021-02-07 19:01:22 +00:00
"github.com/nspcc-dev/neo-go/pkg/services/oracle/broadcaster"
2022-07-22 16:09:29 +00:00
"github.com/nspcc-dev/neo-go/pkg/services/rpcsrv/params"
2022-08-22 15:50:35 +00:00
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
2020-12-29 10:45:49 +00:00
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
2022-08-22 15:50:35 +00:00
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
2022-12-10 08:35:03 +00:00
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest/standard"
2020-11-11 15:43:28 +00:00
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
2020-03-03 14:21:42 +00:00
"github.com/nspcc-dev/neo-go/pkg/util"
2022-08-22 15:50:35 +00:00
"github.com/nspcc-dev/neo-go/pkg/vm"
2021-07-25 12:00:44 +00:00
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
2021-03-10 14:43:52 +00:00
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
2021-10-07 09:03:37 +00:00
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
2019-12-30 08:44:52 +00:00
"go.uber.org/zap"
2018-03-23 20:36:59 +00:00
)
type (
2022-07-22 19:52:58 +00:00
// Ledger abstracts away the Blockchain as used by the RPC server.
Ledger interface {
AddBlock ( block * block . Block ) error
BlockHeight ( ) uint32
2023-09-20 13:33:04 +00:00
CalculateAttributesFee ( tx * transaction . Transaction ) int64
2022-07-22 19:52:58 +00:00
CalculateClaimable ( h util . Uint160 , endHeight uint32 ) ( * big . Int , error )
CurrentBlockHash ( ) util . Uint256
FeePerByte ( ) int64
ForEachNEP11Transfer ( acc util . Uint160 , newestTimestamp uint64 , f func ( * state . NEP11Transfer ) ( bool , error ) ) error
ForEachNEP17Transfer ( acc util . Uint160 , newestTimestamp uint64 , f func ( * state . NEP17Transfer ) ( bool , error ) ) error
GetAppExecResults ( util . Uint256 , trigger . Type ) ( [ ] state . AppExecResult , error )
GetBaseExecFee ( ) int64
GetBlock ( hash util . Uint256 ) ( * block . Block , error )
GetCommittee ( ) ( keys . PublicKeys , error )
2022-12-06 13:34:38 +00:00
GetConfig ( ) config . Blockchain
2022-07-22 19:52:58 +00:00
GetContractScriptHash ( id int32 ) ( util . Uint160 , error )
GetContractState ( hash util . Uint160 ) * state . Contract
GetEnrollments ( ) ( [ ] state . Validator , error )
GetGoverningTokenBalance ( acc util . Uint160 ) ( * big . Int , uint32 )
GetHeader ( hash util . Uint256 ) ( * block . Header , error )
2022-11-18 20:19:50 +00:00
GetHeaderHash ( uint32 ) util . Uint256
2022-07-22 19:52:58 +00:00
GetMaxVerificationGAS ( ) int64
GetMemPool ( ) * mempool . Pool
GetNEP11Contracts ( ) [ ] util . Uint160
GetNEP17Contracts ( ) [ ] util . Uint160
GetNativeContractScriptHash ( string ) ( util . Uint160 , error )
2024-05-16 15:46:00 +00:00
GetNatives ( ) [ ] state . Contract
2022-07-22 19:52:58 +00:00
GetNextBlockValidators ( ) ( [ ] * keys . PublicKey , error )
GetNotaryContractScriptHash ( ) util . Uint160
2022-07-22 20:14:02 +00:00
GetStateModule ( ) core . StateRoot
2022-07-22 19:52:58 +00:00
GetStorageItem ( id int32 , key [ ] byte ) state . StorageItem
2022-10-06 10:24:57 +00:00
GetTestHistoricVM ( t trigger . Type , tx * transaction . Transaction , nextBlockHeight uint32 ) ( * interop . Context , error )
GetTestVM ( t trigger . Type , tx * transaction . Transaction , b * block . Block ) ( * interop . Context , error )
2022-07-22 19:52:58 +00:00
GetTokenLastUpdated ( acc util . Uint160 ) ( map [ int32 ] uint32 , error )
GetTransaction ( util . Uint256 ) ( * transaction . Transaction , uint32 , error )
HeaderHeight ( ) uint32
InitVerificationContext ( ic * interop . Context , hash util . Uint160 , witness * transaction . Witness ) error
2023-04-07 08:26:58 +00:00
P2PSigExtensionsEnabled ( ) bool
2022-08-19 17:47:55 +00:00
SubscribeForBlocks ( ch chan * block . Block )
2023-12-22 08:23:41 +00:00
SubscribeForHeadersOfAddedBlocks ( ch chan * block . Header )
2022-08-19 17:47:55 +00:00
SubscribeForExecutions ( ch chan * state . AppExecResult )
SubscribeForNotifications ( ch chan * state . ContainedNotificationEvent )
SubscribeForTransactions ( ch chan * transaction . Transaction )
UnsubscribeFromBlocks ( ch chan * block . Block )
2023-12-22 08:23:41 +00:00
UnsubscribeFromHeadersOfAddedBlocks ( ch chan * block . Header )
2022-08-19 17:47:55 +00:00
UnsubscribeFromExecutions ( ch chan * state . AppExecResult )
UnsubscribeFromNotifications ( ch chan * state . ContainedNotificationEvent )
UnsubscribeFromTransactions ( ch chan * transaction . Transaction )
2022-07-22 19:52:58 +00:00
VerifyTx ( * transaction . Transaction ) error
VerifyWitness ( util . Uint160 , hash . Hashable , * transaction . Witness , int64 ) ( int64 , error )
mempool . Feer // fee interface
2023-08-24 11:23:42 +00:00
ContractStorageSeeker
}
// ContractStorageSeeker is the interface `findstorage*` handlers need to be able to
2023-11-23 15:44:19 +00:00
// seek over contract storage. Prefix is trimmed in the resulting pair's key.
2023-08-24 11:23:42 +00:00
ContractStorageSeeker interface {
SeekStorage ( id int32 , prefix [ ] byte , cont func ( k , v [ ] byte ) bool )
2022-07-22 19:52:58 +00:00
}
2022-07-26 15:27:33 +00:00
// OracleHandler is the interface oracle service needs to provide for the Server.
OracleHandler interface {
AddResponse ( pub * keys . PublicKey , reqID uint64 , txSig [ ] byte )
}
2018-03-23 20:36:59 +00:00
// Server represents the JSON-RPC 2.0 server.
Server struct {
2022-11-25 10:20:53 +00:00
http [ ] * http . Server
https [ ] * http . Server
2022-07-22 19:52:58 +00:00
chain Ledger
2022-07-22 16:17:48 +00:00
config config . RPC
2022-05-18 09:45:44 +00:00
// wsReadLimit represents web-socket message limit for a receiving side.
wsReadLimit int64
2022-11-09 05:55:57 +00:00
upgrader websocket . Upgrader
2020-11-17 12:57:50 +00:00
network netmode . Magic
stateRootEnabled bool
coreServer * network . Server
2022-07-26 18:36:37 +00:00
oracle * atomic . Value
2020-11-17 12:57:50 +00:00
log * zap . Logger
shutdown chan struct { }
2023-10-11 10:24:16 +00:00
started atomic . Bool
2023-01-23 07:32:04 +00:00
errChan chan <- error
2020-05-10 22:00:19 +00:00
2022-06-15 18:23:29 +00:00
sessionsLock sync . Mutex
sessions map [ string ] * session
2022-11-17 13:00:22 +00:00
subsLock sync . RWMutex
subscribers map [ * subscriber ] bool
subsCounterLock sync . RWMutex
2021-05-28 11:55:06 +00:00
blockSubs int
2023-12-22 08:23:41 +00:00
blockHeaderSubs int
2021-05-28 11:55:06 +00:00
executionSubs int
notificationSubs int
transactionSubs int
notaryRequestSubs int
2022-11-17 13:00:22 +00:00
2023-04-13 08:36:39 +00:00
blockCh chan * block . Block
2023-12-22 08:23:41 +00:00
blockHeaderCh chan * block . Header
2023-04-13 08:36:39 +00:00
executionCh chan * state . AppExecResult
notificationCh chan * state . ContainedNotificationEvent
transactionCh chan * transaction . Transaction
notaryRequestCh chan mempoolevent . Event
subEventsToExitCh chan struct { }
2018-03-23 20:36:59 +00:00
}
2022-06-15 18:23:29 +00:00
// session holds a set of iterators got after invoke* call with corresponding
2022-07-07 19:03:11 +00:00
// finalizer and session expiration timer.
2022-06-15 18:23:29 +00:00
session struct {
2022-07-07 19:03:11 +00:00
// iteratorsLock protects iteratorIdentifiers of the current session.
iteratorsLock sync . Mutex
// iteratorIdentifiers stores the set of Iterator stackitems got either from original invocation
// or from historic MPT-based invocation. In the second case, iteratorIdentifiers are supposed
// to be filled during the first `traverseiterator` call using corresponding params.
iteratorIdentifiers [ ] * iteratorIdentifier
2022-07-08 20:25:22 +00:00
timer * time . Timer
finalize func ( )
}
// iteratorIdentifier represents Iterator on the server side, holding iterator ID and Iterator stackitem.
2022-07-07 19:03:11 +00:00
iteratorIdentifier struct {
ID string
2022-07-08 20:25:22 +00:00
// Item represents Iterator stackitem.
2022-07-07 19:03:11 +00:00
Item stackitem . Item
2022-06-15 18:23:29 +00:00
}
2018-03-23 20:36:59 +00:00
)
2020-04-29 12:25:58 +00:00
const (
// Disconnection timeout.
wsPongLimit = 60 * time . Second
// Ping period for connection liveness check.
wsPingPeriod = wsPongLimit / 2
// Write deadline.
wsWriteLimit = wsPingPeriod / 2
2020-05-10 22:00:19 +00:00
2022-11-23 09:19:49 +00:00
// Default maximum number of websocket clients per Server.
defaultMaxWebSocketClients = 64
2020-09-14 14:48:17 +00:00
// Maximum number of elements for get*transfers requests.
maxTransfersLimit = 1000
2022-07-08 12:42:27 +00:00
// defaultSessionPoolSize is the number of concurrently running iterator sessions.
defaultSessionPoolSize = 20
2020-04-29 12:25:58 +00:00
)
2023-04-03 10:34:24 +00:00
var rpcHandlers = map [ string ] func ( * Server , params . Params ) ( any , * neorpc . Error ) {
2022-04-07 15:13:08 +00:00
"calculatenetworkfee" : ( * Server ) . calculateNetworkFee ,
"findstates" : ( * Server ) . findStates ,
2023-08-22 16:00:43 +00:00
"findstorage" : ( * Server ) . findStorage ,
"findstoragehistoric" : ( * Server ) . findStorageHistoric ,
2022-04-07 15:13:08 +00:00
"getapplicationlog" : ( * Server ) . getApplicationLog ,
"getbestblockhash" : ( * Server ) . getBestBlockHash ,
"getblock" : ( * Server ) . getBlock ,
"getblockcount" : ( * Server ) . getBlockCount ,
"getblockhash" : ( * Server ) . getBlockHash ,
"getblockheader" : ( * Server ) . getBlockHeader ,
"getblockheadercount" : ( * Server ) . getBlockHeaderCount ,
"getblocksysfee" : ( * Server ) . getBlockSysFee ,
2022-07-01 13:02:03 +00:00
"getcandidates" : ( * Server ) . getCandidates ,
2022-04-07 15:13:08 +00:00
"getcommittee" : ( * Server ) . getCommittee ,
"getconnectioncount" : ( * Server ) . getConnectionCount ,
"getcontractstate" : ( * Server ) . getContractState ,
"getnativecontracts" : ( * Server ) . getNativeContracts ,
"getnep11balances" : ( * Server ) . getNEP11Balances ,
"getnep11properties" : ( * Server ) . getNEP11Properties ,
"getnep11transfers" : ( * Server ) . getNEP11Transfers ,
"getnep17balances" : ( * Server ) . getNEP17Balances ,
"getnep17transfers" : ( * Server ) . getNEP17Transfers ,
"getpeers" : ( * Server ) . getPeers ,
"getproof" : ( * Server ) . getProof ,
"getrawmempool" : ( * Server ) . getRawMempool ,
2023-08-22 09:36:11 +00:00
"getrawnotarypool" : ( * Server ) . getRawNotaryPool ,
"getrawnotarytransaction" : ( * Server ) . getRawNotaryTransaction ,
2022-04-07 15:13:08 +00:00
"getrawtransaction" : ( * Server ) . getrawtransaction ,
"getstate" : ( * Server ) . getState ,
"getstateheight" : ( * Server ) . getStateHeight ,
"getstateroot" : ( * Server ) . getStateRoot ,
"getstorage" : ( * Server ) . getStorage ,
2023-08-22 16:29:22 +00:00
"getstoragehistoric" : ( * Server ) . getStorageHistoric ,
2022-04-07 15:13:08 +00:00
"gettransactionheight" : ( * Server ) . getTransactionHeight ,
"getunclaimedgas" : ( * Server ) . getUnclaimedGas ,
"getnextblockvalidators" : ( * Server ) . getNextBlockValidators ,
"getversion" : ( * Server ) . getVersion ,
"invokefunction" : ( * Server ) . invokeFunction ,
"invokefunctionhistoric" : ( * Server ) . invokeFunctionHistoric ,
"invokescript" : ( * Server ) . invokescript ,
"invokescripthistoric" : ( * Server ) . invokescripthistoric ,
"invokecontractverify" : ( * Server ) . invokeContractVerify ,
"invokecontractverifyhistoric" : ( * Server ) . invokeContractVerifyHistoric ,
"sendrawtransaction" : ( * Server ) . sendrawtransaction ,
"submitblock" : ( * Server ) . submitBlock ,
"submitnotaryrequest" : ( * Server ) . submitNotaryRequest ,
"submitoracleresponse" : ( * Server ) . submitOracleResponse ,
2022-06-15 18:23:29 +00:00
"terminatesession" : ( * Server ) . terminateSession ,
"traverseiterator" : ( * Server ) . traverseIterator ,
2022-04-07 15:13:08 +00:00
"validateaddress" : ( * Server ) . validateAddress ,
"verifyproof" : ( * Server ) . verifyProof ,
2020-03-13 07:29:49 +00:00
}
2023-04-03 10:34:24 +00:00
var rpcWsHandlers = map [ string ] func ( * Server , params . Params , * subscriber ) ( any , * neorpc . Error ) {
2020-05-10 22:00:19 +00:00
"subscribe" : ( * Server ) . subscribe ,
"unsubscribe" : ( * Server ) . unsubscribe ,
}
2023-08-09 12:14:06 +00:00
// New creates a new Server struct. Pay attention that orc is expected to be either
// untyped nil or non-nil structure implementing OracleHandler interface.
2022-07-22 19:52:58 +00:00
func New ( chain Ledger , conf config . RPC , coreServer * network . Server ,
2023-01-23 07:32:04 +00:00
orc OracleHandler , log * zap . Logger , errChan chan <- error ) Server {
2022-12-06 13:34:38 +00:00
protoCfg := chain . GetConfig ( ) . ProtocolConfiguration
2022-07-08 12:42:27 +00:00
if conf . SessionEnabled {
if conf . SessionExpirationTime <= 0 {
2024-08-23 19:09:20 +00:00
conf . SessionExpirationTime = max ( int ( protoCfg . TimePerBlock / time . Second ) , 5 )
2022-12-02 16:10:45 +00:00
log . Info ( "SessionExpirationTime is not set or wrong, setting default value" , zap . Int ( "SessionExpirationTime" , conf . SessionExpirationTime ) )
2022-07-08 12:42:27 +00:00
}
if conf . SessionPoolSize <= 0 {
conf . SessionPoolSize = defaultSessionPoolSize
log . Info ( "SessionPoolSize is not set or wrong, setting default value" , zap . Int ( "SessionPoolSize" , defaultSessionPoolSize ) )
}
2022-07-05 16:29:18 +00:00
}
2023-08-29 09:32:00 +00:00
if conf . MaxIteratorResultItems <= 0 {
conf . MaxIteratorResultItems = config . DefaultMaxIteratorResultItems
log . Info ( "MaxIteratorResultItems is not set or wrong, setting default value" , zap . Int ( "MaxIteratorResultItems" , config . DefaultMaxIteratorResultItems ) )
}
2023-08-29 09:34:53 +00:00
if conf . MaxFindResultItems <= 0 {
conf . MaxFindResultItems = config . DefaultMaxFindResultItems
log . Info ( "MaxFindResultItems is not set or wrong, setting default value" , zap . Int ( "MaxFindResultItems" , config . DefaultMaxFindResultItems ) )
}
2023-08-29 09:59:41 +00:00
if conf . MaxFindStorageResultItems <= 0 {
conf . MaxFindStorageResultItems = config . DefaultMaxFindStorageResultItems
log . Info ( "MaxFindStorageResultItems is not set or wrong, setting default value" , zap . Int ( "MaxFindStorageResultItems" , config . DefaultMaxFindStorageResultItems ) )
}
2023-08-29 10:03:52 +00:00
if conf . MaxNEP11Tokens <= 0 {
conf . MaxNEP11Tokens = config . DefaultMaxNEP11Tokens
log . Info ( "MaxNEP11Tokens is not set or wrong, setting default value" , zap . Int ( "MaxNEP11Tokens" , config . DefaultMaxNEP11Tokens ) )
}
2023-11-23 10:23:22 +00:00
if conf . MaxRequestBodyBytes <= 0 {
conf . MaxRequestBodyBytes = config . DefaultMaxRequestBodyBytes
log . Info ( "MaxRequestBodyBytes is not set or wong, setting default value" , zap . Int ( "MaxRequestBodyBytes" , config . DefaultMaxRequestBodyBytes ) )
}
2023-11-23 10:39:24 +00:00
if conf . MaxRequestHeaderBytes <= 0 {
conf . MaxRequestHeaderBytes = config . DefaultMaxRequestHeaderBytes
log . Info ( "MaxRequestHeaderBytes is not set or wong, setting default value" , zap . Int ( "MaxRequestHeaderBytes" , config . DefaultMaxRequestHeaderBytes ) )
}
2022-11-23 09:19:49 +00:00
if conf . MaxWebSocketClients == 0 {
conf . MaxWebSocketClients = defaultMaxWebSocketClients
log . Info ( "MaxWebSocketClients is not set or wrong, setting default value" , zap . Int ( "MaxWebSocketClients" , defaultMaxWebSocketClients ) )
}
2022-07-26 18:36:37 +00:00
var oracleWrapped = new ( atomic . Value )
if orc != nil {
2023-08-09 12:14:06 +00:00
oracleWrapped . Store ( orc )
2022-07-26 18:36:37 +00:00
}
2022-11-09 05:55:57 +00:00
var wsOriginChecker func ( * http . Request ) bool
if conf . EnableCORSWorkaround {
wsOriginChecker = func ( _ * http . Request ) bool { return true }
}
2023-11-23 10:39:24 +00:00
addrs := conf . Addresses
httpServers := make ( [ ] * http . Server , len ( addrs ) )
for i , addr := range addrs {
httpServers [ i ] = & http . Server {
Addr : addr ,
MaxHeaderBytes : conf . MaxRequestHeaderBytes ,
}
}
var tlsServers [ ] * http . Server
if cfg := conf . TLSConfig ; cfg . Enabled {
addrs := cfg . Addresses
tlsServers = make ( [ ] * http . Server , len ( addrs ) )
for i , addr := range addrs {
tlsServers [ i ] = & http . Server {
Addr : addr ,
MaxHeaderBytes : conf . MaxRequestHeaderBytes ,
}
}
}
2018-03-23 20:36:59 +00:00
return Server {
2022-11-25 10:20:53 +00:00
http : httpServers ,
https : tlsServers ,
2020-11-17 12:57:50 +00:00
chain : chain ,
config : conf ,
2022-07-05 16:29:18 +00:00
wsReadLimit : int64 ( protoCfg . MaxBlockSize * 4 ) / 3 + 1024 , // Enough for Base64-encoded content of `submitblock` and `submitp2pnotaryrequest`.
2022-11-09 05:55:57 +00:00
upgrader : websocket . Upgrader { CheckOrigin : wsOriginChecker } ,
2022-07-05 16:29:18 +00:00
network : protoCfg . Magic ,
stateRootEnabled : protoCfg . StateRootInHeader ,
2020-11-17 12:57:50 +00:00
coreServer : coreServer ,
log : log ,
2022-07-26 18:36:37 +00:00
oracle : oracleWrapped ,
2020-11-17 12:57:50 +00:00
shutdown : make ( chan struct { } ) ,
2022-04-22 07:49:06 +00:00
errChan : errChan ,
2020-05-10 22:00:19 +00:00
2022-06-15 18:23:29 +00:00
sessions : make ( map [ string ] * session ) ,
2020-05-10 22:00:19 +00:00
subscribers : make ( map [ * subscriber ] bool ) ,
// These are NOT buffered to preserve original order of events.
2023-04-13 08:36:39 +00:00
blockCh : make ( chan * block . Block ) ,
executionCh : make ( chan * state . AppExecResult ) ,
notificationCh : make ( chan * state . ContainedNotificationEvent ) ,
transactionCh : make ( chan * transaction . Transaction ) ,
notaryRequestCh : make ( chan mempoolevent . Event ) ,
2023-12-22 08:23:41 +00:00
blockHeaderCh : make ( chan * block . Header ) ,
2023-04-13 08:36:39 +00:00
subEventsToExitCh : make ( chan struct { } ) ,
2018-03-23 20:36:59 +00:00
}
}
2022-04-22 08:33:56 +00:00
// Name returns service name.
func ( s * Server ) Name ( ) string {
return "rpc"
}
2022-04-22 07:49:06 +00:00
// Start creates a new JSON-RPC server listening on the configured port. It creates
// goroutines needed internally and it returns its errors via errChan passed to New().
2022-07-04 20:03:50 +00:00
// The Server only starts once, subsequent calls to Start are no-op.
2022-04-22 07:49:06 +00:00
func ( s * Server ) Start ( ) {
2019-11-01 10:23:46 +00:00
if ! s . config . Enabled {
2019-12-30 08:44:52 +00:00
s . log . Info ( "RPC server is not enabled" )
2019-11-01 10:23:46 +00:00
return
}
2023-04-27 15:49:19 +00:00
if ! s . started . CompareAndSwap ( false , true ) {
2022-04-22 07:33:52 +00:00
s . log . Info ( "RPC server already started" )
return
}
2023-04-13 08:03:18 +00:00
go s . handleSubEvents ( )
2022-11-25 10:20:53 +00:00
for _ , srv := range s . http {
srv . Handler = http . HandlerFunc ( s . handleHTTPRequest )
s . log . Info ( "starting rpc-server" , zap . String ( "endpoint" , srv . Addr ) )
ln , err := net . Listen ( "tcp" , srv . Addr )
if err != nil {
s . errChan <- fmt . Errorf ( "failed to listen on %s: %w" , srv . Addr , err )
return
}
srv . Addr = ln . Addr ( ) . String ( ) // set Addr to the actual address
go func ( server * http . Server ) {
err = server . Serve ( ln )
if ! errors . Is ( err , http . ErrServerClosed ) {
s . log . Error ( "failed to start RPC server" , zap . Error ( err ) )
s . errChan <- err
}
} ( srv )
}
2018-03-23 20:36:59 +00:00
2020-03-10 11:56:18 +00:00
if cfg := s . config . TLSConfig ; cfg . Enabled {
2022-11-25 10:20:53 +00:00
for _ , srv := range s . https {
srv . Handler = http . HandlerFunc ( s . handleHTTPRequest )
s . log . Info ( "starting rpc-server (https)" , zap . String ( "endpoint" , srv . Addr ) )
ln , err := net . Listen ( "tcp" , srv . Addr )
2020-08-31 12:35:55 +00:00
if err != nil {
2022-04-22 07:49:06 +00:00
s . errChan <- err
2020-08-31 12:35:55 +00:00
return
}
2022-11-25 10:20:53 +00:00
srv . Addr = ln . Addr ( ) . String ( )
go func ( srv * http . Server ) {
err = srv . ServeTLS ( ln , cfg . CertFile , cfg . KeyFile )
if ! errors . Is ( err , http . ErrServerClosed ) {
s . log . Error ( "failed to start TLS RPC server" ,
zap . String ( "endpoint" , srv . Addr ) , zap . Error ( err ) )
s . errChan <- err
}
} ( srv )
2020-08-31 12:35:55 +00:00
}
2022-11-25 10:20:53 +00:00
}
2018-03-23 20:36:59 +00:00
}
2022-07-04 20:03:50 +00:00
// Shutdown stops the RPC server if it's running. It can only be called once,
// subsequent calls to Shutdown on the same instance are no-op. The instance
// that was stopped can not be started again by calling Start (use a new
// instance if needed).
2022-04-22 07:49:06 +00:00
func ( s * Server ) Shutdown ( ) {
2023-04-27 15:49:19 +00:00
if ! s . started . CompareAndSwap ( true , false ) {
2022-04-22 08:47:36 +00:00
return
}
2020-05-10 22:00:19 +00:00
// Signal to websocket writer routines and handleSubEvents.
close ( s . shutdown )
2020-03-10 11:56:18 +00:00
if s . config . TLSConfig . Enabled {
2022-11-25 10:20:53 +00:00
for _ , srv := range s . https {
s . log . Info ( "shutting down RPC server (https)" , zap . String ( "endpoint" , srv . Addr ) )
err := srv . Shutdown ( context . Background ( ) )
if err != nil {
s . log . Warn ( "error during RPC (https) server shutdown" ,
zap . String ( "endpoint" , srv . Addr ) , zap . Error ( err ) )
}
2022-04-25 21:13:13 +00:00
}
2020-03-10 11:56:18 +00:00
}
2022-11-25 10:20:53 +00:00
for _ , srv := range s . http {
s . log . Info ( "shutting down RPC server" , zap . String ( "endpoint" , srv . Addr ) )
err := srv . Shutdown ( context . Background ( ) )
if err != nil {
s . log . Warn ( "error during RPC (http) server shutdown" ,
zap . String ( "endpoint" , srv . Addr ) , zap . Error ( err ) )
}
2022-04-25 21:13:13 +00:00
}
2020-05-10 22:00:19 +00:00
2022-06-15 18:23:29 +00:00
// Perform sessions finalisation.
if s . config . SessionEnabled {
s . sessionsLock . Lock ( )
for _ , session := range s . sessions {
// Concurrent iterator traversal may still be in process, thus need to protect iteratorIdentifiers access.
session . iteratorsLock . Lock ( )
2022-07-08 20:25:22 +00:00
session . finalize ( )
2022-06-15 18:23:29 +00:00
if ! session . timer . Stop ( ) {
<- session . timer . C
}
session . iteratorsLock . Unlock ( )
}
s . sessions = nil
s . sessionsLock . Unlock ( )
}
2020-05-10 22:00:19 +00:00
// Wait for handleSubEvents to finish.
2023-04-13 08:36:39 +00:00
<- s . subEventsToExitCh
2024-02-18 12:29:04 +00:00
_ = s . log . Sync ( )
2018-03-23 20:36:59 +00:00
}
2022-07-26 18:36:37 +00:00
// SetOracleHandler allows to update oracle handler used by the Server.
func ( s * Server ) SetOracleHandler ( orc OracleHandler ) {
2023-08-09 12:14:06 +00:00
s . oracle . Store ( orc )
2022-07-26 18:36:37 +00:00
}
2020-04-28 13:56:33 +00:00
func ( s * Server ) handleHTTPRequest ( w http . ResponseWriter , httpRequest * http . Request ) {
2023-11-23 10:23:22 +00:00
// Restrict request body before further processing.
httpRequest . Body = http . MaxBytesReader ( w , httpRequest . Body , int64 ( s . config . MaxRequestBodyBytes ) )
2022-07-07 14:41:01 +00:00
req := params . NewRequest ( )
2020-05-10 22:00:19 +00:00
2020-04-29 12:25:58 +00:00
if httpRequest . URL . Path == "/ws" && httpRequest . Method == "GET" {
2020-05-10 22:00:19 +00:00
// Technically there is a race between this check and
// s.subscribers modification 20 lines below, but it's tiny
// and not really critical to bother with it. Some additional
// clients may sneak in, no big deal.
s . subsLock . RLock ( )
numOfSubs := len ( s . subscribers )
s . subsLock . RUnlock ( )
2022-11-23 09:19:49 +00:00
if numOfSubs >= s . config . MaxWebSocketClients {
2020-05-10 22:00:19 +00:00
s . writeHTTPErrorResponse (
2022-07-07 14:41:01 +00:00
params . NewIn ( ) ,
2020-05-10 22:00:19 +00:00
w ,
2022-07-22 16:09:29 +00:00
neorpc . NewInternalServerError ( "websocket users limit reached" ) ,
2020-05-10 22:00:19 +00:00
)
return
}
2022-11-09 05:55:57 +00:00
ws , err := s . upgrader . Upgrade ( w , httpRequest , nil )
2020-04-29 12:25:58 +00:00
if err != nil {
s . log . Info ( "websocket connection upgrade failed" , zap . Error ( err ) )
return
}
2022-06-09 15:19:01 +00:00
resChan := make ( chan abstractResult ) // response.abstract or response.abstractBatch
2023-02-15 07:07:47 +00:00
subChan := make ( chan intEvent , notificationBufSize )
2023-02-15 13:45:37 +00:00
subscr := & subscriber { writer : subChan }
2020-05-10 22:00:19 +00:00
s . subsLock . Lock ( )
s . subscribers [ subscr ] = true
s . subsLock . Unlock ( )
go s . handleWsWrites ( ws , resChan , subChan )
s . handleWsReads ( ws , resChan , subscr )
2020-04-29 12:25:58 +00:00
return
}
2022-10-04 18:50:46 +00:00
if httpRequest . Method == "OPTIONS" && s . config . EnableCORSWorkaround { // Preflight CORS.
setCORSOriginHeaders ( w . Header ( ) )
w . Header ( ) . Set ( "Access-Control-Allow-Methods" , "GET, POST" ) // GET for websockets.
w . Header ( ) . Set ( "Access-Control-Max-Age" , "21600" ) // 6 hours.
return
}
2018-03-23 20:36:59 +00:00
if httpRequest . Method != "POST" {
2020-04-28 19:56:19 +00:00
s . writeHTTPErrorResponse (
2022-07-07 14:41:01 +00:00
params . NewIn ( ) ,
2018-03-23 20:36:59 +00:00
w ,
2022-07-22 16:09:29 +00:00
neorpc . NewInvalidParamsError ( fmt . Sprintf ( "invalid method '%s', please retry with 'POST'" , httpRequest . Method ) ) ,
2018-03-23 20:36:59 +00:00
)
return
}
err := req . DecodeData ( httpRequest . Body )
if err != nil {
2022-07-22 16:09:29 +00:00
s . writeHTTPErrorResponse ( params . NewIn ( ) , w , neorpc . NewParseError ( err . Error ( ) ) )
2018-03-23 20:36:59 +00:00
return
}
2020-05-10 22:00:19 +00:00
resp := s . handleRequest ( req , nil )
2020-04-28 19:56:19 +00:00
s . writeHTTPServerResponse ( req , w , resp )
2020-04-28 13:56:33 +00:00
}
2023-02-15 07:07:47 +00:00
// RegisterLocal performs local client registration.
func ( s * Server ) RegisterLocal ( ctx context . Context , events chan <- neorpc . Notification ) func ( * neorpc . Request ) ( * neorpc . Response , error ) {
subChan := make ( chan intEvent , notificationBufSize )
subscr := & subscriber { writer : subChan }
s . subsLock . Lock ( )
s . subscribers [ subscr ] = true
s . subsLock . Unlock ( )
go s . handleLocalNotifications ( ctx , events , subChan , subscr )
return func ( req * neorpc . Request ) ( * neorpc . Response , error ) {
return s . handleInternal ( req , subscr )
}
}
2022-07-07 14:41:01 +00:00
func ( s * Server ) handleRequest ( req * params . Request , sub * subscriber ) abstractResult {
2020-10-26 17:22:20 +00:00
if req . In != nil {
2022-03-21 20:36:19 +00:00
req . In . Method = escapeForLog ( req . In . Method ) // No valid method name will be changed by it.
2020-10-26 17:22:20 +00:00
return s . handleIn ( req . In , sub )
}
2022-06-09 15:19:01 +00:00
resp := make ( abstractBatch , len ( req . Batch ) )
2020-10-26 17:22:20 +00:00
for i , in := range req . Batch {
2022-03-21 20:36:19 +00:00
in . Method = escapeForLog ( in . Method ) // No valid method name will be changed by it.
2020-10-26 17:22:20 +00:00
resp [ i ] = s . handleIn ( & in , sub )
}
return resp
}
2023-02-15 07:07:47 +00:00
// handleInternal is an experimental interface to handle client requests directly.
func ( s * Server ) handleInternal ( req * neorpc . Request , sub * subscriber ) ( * neorpc . Response , error ) {
var (
2023-04-03 10:34:24 +00:00
res any
2023-02-15 07:07:47 +00:00
rpcRes = & neorpc . Response {
HeaderAndError : neorpc . HeaderAndError {
Header : neorpc . Header {
JSONRPC : req . JSONRPC ,
ID : json . RawMessage ( strconv . FormatUint ( req . ID , 10 ) ) ,
} ,
} ,
}
)
reqParams , err := params . FromAny ( req . Params )
if err != nil {
return nil , err
}
s . log . Debug ( "processing local rpc request" ,
zap . String ( "method" , req . Method ) ,
zap . Stringer ( "params" , reqParams ) )
start := time . Now ( )
defer func ( ) { addReqTimeMetric ( req . Method , time . Since ( start ) ) } ( )
rpcRes . Error = neorpc . NewMethodNotFoundError ( fmt . Sprintf ( "method %q not supported" , req . Method ) )
handler , ok := rpcHandlers [ req . Method ]
if ok {
res , rpcRes . Error = handler ( s , reqParams )
} else if sub != nil {
handler , ok := rpcWsHandlers [ req . Method ]
if ok {
res , rpcRes . Error = handler ( s , reqParams , sub )
}
}
if res != nil {
b , err := json . Marshal ( res )
if err != nil {
return nil , fmt . Errorf ( "response can't be JSONized: %w" , err )
}
rpcRes . Result = json . RawMessage ( b )
}
return rpcRes , nil
}
2022-07-07 14:41:01 +00:00
func ( s * Server ) handleIn ( req * params . In , sub * subscriber ) abstract {
2023-04-03 10:34:24 +00:00
var res any
2022-07-22 16:09:29 +00:00
var resErr * neorpc . Error
if req . JSONRPC != neorpc . JSONRPCVersion {
return s . packResponse ( req , nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "problem parsing JSON: invalid version, expected 2.0 got '%s'" , req . JSONRPC ) ) )
2020-10-26 17:22:20 +00:00
}
2020-05-10 22:00:19 +00:00
2022-07-07 14:41:01 +00:00
reqParams := params . Params ( req . RawParams )
2018-03-23 20:36:59 +00:00
2020-01-13 13:45:36 +00:00
s . log . Debug ( "processing rpc request" ,
2019-12-30 08:44:52 +00:00
zap . String ( "method" , req . Method ) ,
2020-10-08 13:29:30 +00:00
zap . Stringer ( "params" , reqParams ) )
2018-03-23 20:36:59 +00:00
2022-11-09 10:26:45 +00:00
start := time . Now ( )
defer func ( ) { addReqTimeMetric ( req . Method , time . Since ( start ) ) } ( )
2020-03-12 17:36:36 +00:00
2022-07-22 16:09:29 +00:00
resErr = neorpc . NewMethodNotFoundError ( fmt . Sprintf ( "method %q not supported" , req . Method ) )
2020-03-13 07:29:49 +00:00
handler , ok := rpcHandlers [ req . Method ]
2020-05-10 22:00:19 +00:00
if ok {
2021-10-28 11:10:18 +00:00
res , resErr = handler ( s , reqParams )
2020-05-10 22:00:19 +00:00
} else if sub != nil {
handler , ok := rpcWsHandlers [ req . Method ]
if ok {
2021-10-28 11:10:18 +00:00
res , resErr = handler ( s , reqParams , sub )
2020-05-10 22:00:19 +00:00
}
2018-03-23 20:36:59 +00:00
}
2020-08-31 15:27:32 +00:00
return s . packResponse ( req , res , resErr )
2020-03-13 07:01:49 +00:00
}
2023-02-15 07:07:47 +00:00
func ( s * Server ) handleLocalNotifications ( ctx context . Context , events chan <- neorpc . Notification , subChan <- chan intEvent , subscr * subscriber ) {
eventloop :
for {
select {
case <- s . shutdown :
break eventloop
case <- ctx . Done ( ) :
break eventloop
case ev := <- subChan :
events <- * ev . ntf // Make a copy.
}
}
close ( events )
s . dropSubscriber ( subscr )
drainloop :
for {
select {
case <- subChan :
default :
break drainloop
}
}
}
func ( s * Server ) handleWsWrites ( ws * websocket . Conn , resChan <- chan abstractResult , subChan <- chan intEvent ) {
2020-04-29 12:25:58 +00:00
pingTicker := time . NewTicker ( wsPingPeriod )
2020-05-12 19:38:29 +00:00
eventloop :
2020-04-29 12:25:58 +00:00
for {
select {
2020-05-10 22:00:19 +00:00
case <- s . shutdown :
2020-05-12 19:38:29 +00:00
break eventloop
2020-05-10 22:00:19 +00:00
case event , ok := <- subChan :
if ! ok {
2020-05-12 19:38:29 +00:00
break eventloop
2020-05-10 22:00:19 +00:00
}
2021-05-12 18:45:32 +00:00
if err := ws . SetWriteDeadline ( time . Now ( ) . Add ( wsWriteLimit ) ) ; err != nil {
break eventloop
}
2023-02-15 07:07:47 +00:00
if err := ws . WritePreparedMessage ( event . msg ) ; err != nil {
2020-05-12 19:38:29 +00:00
break eventloop
2020-05-10 22:00:19 +00:00
}
2020-04-29 12:25:58 +00:00
case res , ok := <- resChan :
if ! ok {
2020-05-12 19:38:29 +00:00
break eventloop
2020-04-29 12:25:58 +00:00
}
2021-05-12 18:45:32 +00:00
if err := ws . SetWriteDeadline ( time . Now ( ) . Add ( wsWriteLimit ) ) ; err != nil {
break eventloop
}
2020-04-29 12:25:58 +00:00
if err := ws . WriteJSON ( res ) ; err != nil {
2020-05-12 19:38:29 +00:00
break eventloop
2020-04-29 12:25:58 +00:00
}
case <- pingTicker . C :
2021-05-12 18:45:32 +00:00
if err := ws . SetWriteDeadline ( time . Now ( ) . Add ( wsWriteLimit ) ) ; err != nil {
break eventloop
}
2020-04-29 12:25:58 +00:00
if err := ws . WriteMessage ( websocket . PingMessage , [ ] byte { } ) ; err != nil {
2020-05-12 19:38:29 +00:00
break eventloop
2020-04-29 12:25:58 +00:00
}
}
}
2020-05-12 19:38:29 +00:00
ws . Close ( )
pingTicker . Stop ( )
// Drain notification channel as there might be some goroutines blocked
// on it.
drainloop :
for {
select {
case _ , ok := <- subChan :
if ! ok {
break drainloop
}
default :
break drainloop
}
}
2020-04-29 12:25:58 +00:00
}
2022-06-09 15:19:01 +00:00
func ( s * Server ) handleWsReads ( ws * websocket . Conn , resChan chan <- abstractResult , subscr * subscriber ) {
2022-05-18 09:45:44 +00:00
ws . SetReadLimit ( s . wsReadLimit )
2021-05-12 18:45:32 +00:00
err := ws . SetReadDeadline ( time . Now ( ) . Add ( wsPongLimit ) )
ws . SetPongHandler ( func ( string ) error { return ws . SetReadDeadline ( time . Now ( ) . Add ( wsPongLimit ) ) } )
2020-05-10 22:00:19 +00:00
requestloop :
2021-05-12 18:45:32 +00:00
for err == nil {
2022-07-07 14:41:01 +00:00
req := params . NewRequest ( )
2020-04-29 12:25:58 +00:00
err := ws . ReadJSON ( req )
if err != nil {
break
}
2020-05-10 22:00:19 +00:00
res := s . handleRequest ( req , subscr )
2022-07-22 16:09:29 +00:00
res . RunForErrors ( func ( jsonErr * neorpc . Error ) {
2020-10-26 17:22:20 +00:00
s . logRequestError ( req , jsonErr )
} )
2020-05-10 22:00:19 +00:00
select {
case <- s . shutdown :
break requestloop
case resChan <- res :
}
}
2023-02-15 07:07:47 +00:00
s . dropSubscriber ( subscr )
close ( resChan )
ws . Close ( )
}
2022-11-17 13:00:22 +00:00
2023-02-15 07:07:47 +00:00
func ( s * Server ) dropSubscriber ( subscr * subscriber ) {
2020-05-10 22:00:19 +00:00
s . subsLock . Lock ( )
delete ( s . subscribers , subscr )
2022-11-17 13:00:22 +00:00
s . subsLock . Unlock ( )
s . subsCounterLock . Lock ( )
2020-05-10 22:00:19 +00:00
for _ , e := range subscr . feeds {
2022-07-22 16:09:29 +00:00
if e . event != neorpc . InvalidEventID {
2020-05-13 14:13:33 +00:00
s . unsubscribeFromChannel ( e . event )
2020-05-10 22:00:19 +00:00
}
2020-04-29 12:25:58 +00:00
}
2022-11-17 13:00:22 +00:00
s . subsCounterLock . Unlock ( )
2020-04-29 12:25:58 +00:00
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getBestBlockHash ( _ params . Params ) ( any , * neorpc . Error ) {
2020-03-13 07:14:48 +00:00
return "0x" + s . chain . CurrentBlockHash ( ) . StringLE ( ) , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getBlockCount ( _ params . Params ) ( any , * neorpc . Error ) {
2020-03-13 07:14:48 +00:00
return s . chain . BlockHeight ( ) + 1 , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getBlockHeaderCount ( _ params . Params ) ( any , * neorpc . Error ) {
2021-02-07 19:01:22 +00:00
return s . chain . HeaderHeight ( ) + 1 , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getConnectionCount ( _ params . Params ) ( any , * neorpc . Error ) {
2020-03-13 07:14:48 +00:00
return s . coreServer . PeerCount ( ) , nil
}
2022-07-22 16:09:29 +00:00
func ( s * Server ) blockHashFromParam ( param * params . Param ) ( util . Uint256 , * neorpc . Error ) {
2021-10-29 14:06:45 +00:00
var (
hash util . Uint256
err error
)
2020-06-04 11:58:47 +00:00
if param == nil {
2022-07-22 16:09:29 +00:00
return hash , neorpc . ErrInvalidParams
2020-06-04 11:58:47 +00:00
}
2021-10-29 14:06:45 +00:00
if hash , err = param . GetUint256 ( ) ; err != nil {
num , respErr := s . blockHeightFromParam ( param )
if respErr != nil {
return hash , respErr
2020-03-13 07:08:30 +00:00
}
hash = s . chain . GetHeaderHash ( num )
2020-06-05 13:02:55 +00:00
}
return hash , nil
}
2022-07-08 11:50:00 +00:00
func ( s * Server ) fillBlockMetadata ( obj io . Serializable , h * block . Header ) result . BlockMetadata {
res := result . BlockMetadata {
Size : io . GetVarSize ( obj ) , // obj can be a Block or a Header.
Confirmations : s . chain . BlockHeight ( ) - h . Index + 1 ,
}
2022-11-18 20:19:50 +00:00
hash := s . chain . GetHeaderHash ( h . Index + 1 )
2022-07-08 11:50:00 +00:00
if ! hash . Equals ( util . Uint256 { } ) {
res . NextBlockHash = & hash
}
return res
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getBlock ( reqParams params . Params ) ( any , * neorpc . Error ) {
2020-06-04 11:58:47 +00:00
param := reqParams . Value ( 0 )
2020-06-05 13:02:55 +00:00
hash , respErr := s . blockHashFromParam ( param )
if respErr != nil {
return nil , respErr
}
2020-03-13 07:08:30 +00:00
block , err := s . chain . GetBlock ( hash )
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrUnknownBlock , err . Error ( ) )
2020-03-13 07:08:30 +00:00
}
2021-10-28 11:10:18 +00:00
if v , _ := reqParams . Value ( 1 ) . GetBoolean ( ) ; v {
2022-07-08 11:50:00 +00:00
res := result . Block {
Block : * block ,
BlockMetadata : s . fillBlockMetadata ( block , & block . Header ) ,
}
return res , nil
2020-03-13 07:08:30 +00:00
}
writer := io . NewBufBinWriter ( )
block . EncodeBinary ( writer . BinWriter )
2020-11-06 14:37:58 +00:00
return writer . Bytes ( ) , nil
2020-03-13 07:08:30 +00:00
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getBlockHash ( reqParams params . Params ) ( any , * neorpc . Error ) {
2021-10-28 11:10:18 +00:00
num , err := s . blockHeightFromParam ( reqParams . Value ( 0 ) )
2020-03-13 07:06:52 +00:00
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , err
2020-03-13 07:06:52 +00:00
}
return s . chain . GetHeaderHash ( num ) , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getVersion ( _ params . Params ) ( any , * neorpc . Error ) {
2022-11-29 14:43:08 +00:00
port , err := s . coreServer . Port ( nil ) // any port will suite
2020-06-10 07:01:21 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "cannot fetch tcp port: %s" , err ) )
2020-06-10 07:01:21 +00:00
}
2021-09-07 12:42:04 +00:00
cfg := s . chain . GetConfig ( )
2023-10-12 14:54:19 +00:00
hfs := make ( map [ config . Hardfork ] uint32 , len ( cfg . Hardforks ) )
for _ , cfgHf := range config . Hardforks {
height , ok := cfg . Hardforks [ cfgHf . String ( ) ]
if ! ok {
continue
}
hfs [ cfgHf ] = height
}
2024-08-09 09:53:31 +00:00
standbyCommittee , err := keys . NewPublicKeysFromStrings ( cfg . StandbyCommittee )
if err != nil {
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "cannot fetch standbyCommittee: %s" , err ) )
}
2022-04-26 09:32:06 +00:00
return & result . Version {
2022-11-10 13:32:49 +00:00
TCPPort : port ,
Nonce : s . coreServer . ID ( ) ,
UserAgent : s . coreServer . UserAgent ,
2024-04-01 14:56:17 +00:00
RPC : result . RPC {
MaxIteratorResultItems : s . config . MaxIteratorResultItems ,
SessionEnabled : s . config . SessionEnabled ,
} ,
2021-09-07 12:42:04 +00:00
Protocol : result . Protocol {
AddressVersion : address . NEO3Prefix ,
Network : cfg . Magic ,
2022-12-02 16:10:45 +00:00
MillisecondsPerBlock : int ( cfg . TimePerBlock / time . Millisecond ) ,
2021-09-07 12:42:04 +00:00
MaxTraceableBlocks : cfg . MaxTraceableBlocks ,
MaxValidUntilBlockIncrement : cfg . MaxValidUntilBlockIncrement ,
MaxTransactionsPerBlock : cfg . MaxTransactionsPerBlock ,
MemoryPoolMaxTransactions : cfg . MemPoolSize ,
2022-01-21 02:33:06 +00:00
ValidatorsCount : byte ( cfg . GetNumOfCNs ( s . chain . BlockHeight ( ) ) ) ,
2022-04-25 13:01:30 +00:00
InitialGasDistribution : cfg . InitialGASSupply ,
2023-10-12 14:54:19 +00:00
Hardforks : hfs ,
2024-08-09 09:53:31 +00:00
StandbyCommittee : standbyCommittee ,
SeedList : cfg . SeedList ,
2022-08-08 13:10:02 +00:00
CommitteeHistory : cfg . CommitteeHistory ,
P2PSigExtensions : cfg . P2PSigExtensions ,
StateRootInHeader : cfg . StateRootInHeader ,
ValidatorsHistory : cfg . ValidatorsHistory ,
2021-09-07 12:42:04 +00:00
} ,
2020-03-13 07:04:57 +00:00
} , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getPeers ( _ params . Params ) ( any , * neorpc . Error ) {
2020-03-13 07:03:58 +00:00
peers := result . NewGetPeers ( )
peers . AddUnconnected ( s . coreServer . UnconnectedPeers ( ) )
peers . AddConnected ( s . coreServer . ConnectedPeers ( ) )
peers . AddBad ( s . coreServer . BadPeers ( ) )
return peers , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getRawMempool ( reqParams params . Params ) ( any , * neorpc . Error ) {
2021-10-28 11:10:18 +00:00
verbose , _ := reqParams . Value ( 0 ) . GetBoolean ( )
2020-03-13 07:03:01 +00:00
mp := s . chain . GetMemPool ( )
2024-08-24 12:30:39 +00:00
txes := mp . GetVerifiedTransactions ( )
hashList := make ( [ ] util . Uint256 , len ( txes ) )
for i := range txes {
hashList [ i ] = txes [ i ] . Hash ( )
2020-03-13 07:03:01 +00:00
}
2020-07-27 14:27:21 +00:00
if ! verbose {
return hashList , nil
}
return result . RawMempool {
2021-09-09 13:24:22 +00:00
Height : s . chain . BlockHeight ( ) ,
Verified : hashList ,
Unverified : [ ] util . Uint256 { } , // avoid `null` result
2020-07-27 14:27:21 +00:00
} , nil
2020-03-13 07:03:01 +00:00
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) validateAddress ( reqParams params . Params ) ( any , * neorpc . Error ) {
2021-10-28 11:10:18 +00:00
param , err := reqParams . Value ( 0 ) . GetString ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-03-13 07:01:49 +00:00
}
2021-10-28 11:10:18 +00:00
return result . ValidateAddress {
Address : reqParams . Value ( 0 ) ,
IsValid : validateAddress ( param ) ,
} , nil
2018-03-25 10:13:47 +00:00
}
2021-03-24 17:32:48 +00:00
// calculateNetworkFee calculates network fee for the transaction.
2023-04-03 10:34:24 +00:00
func ( s * Server ) calculateNetworkFee ( reqParams params . Params ) ( any , * neorpc . Error ) {
2021-03-24 17:32:48 +00:00
if len ( reqParams ) < 1 {
2022-07-22 16:09:29 +00:00
return 0 , neorpc . ErrInvalidParams
2021-03-24 17:32:48 +00:00
}
byteTx , err := reqParams [ 0 ] . GetBytesBase64 ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return 0 , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , err . Error ( ) )
2021-03-24 17:32:48 +00:00
}
tx , err := transaction . NewTransactionFromBytes ( byteTx )
if err != nil {
2022-07-22 16:09:29 +00:00
return 0 , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , err . Error ( ) )
2021-03-24 17:32:48 +00:00
}
hashablePart , err := tx . EncodeHashableFields ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return 0 , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , fmt . Sprintf ( "failed to compute tx size: %s" , err ) )
2021-03-24 17:32:48 +00:00
}
size := len ( hashablePart ) + io . GetVarSize ( len ( tx . Signers ) )
2023-09-27 16:31:21 +00:00
var (
netFee int64
2024-08-23 19:09:20 +00:00
// Verification GAS cost can't exceed chin policy, but RPC config can limit it further.
gasLimit = min ( s . chain . GetMaxVerificationGAS ( ) , int64 ( s . config . MaxGasInvoke ) )
2023-09-27 16:31:21 +00:00
)
2021-03-24 17:32:48 +00:00
for i , signer := range tx . Signers {
2022-08-22 11:47:30 +00:00
w := tx . Scripts [ i ]
2022-08-22 15:50:35 +00:00
if len ( w . InvocationScript ) == 0 { // No invocation provided, try to infer one.
var paramz [ ] manifest . Parameter
if len ( w . VerificationScript ) == 0 { // Contract-based verification
cs := s . chain . GetContractState ( signer . Account )
if cs == nil {
2023-08-14 16:43:19 +00:00
return 0 , neorpc . WrapErrorWithData ( neorpc . ErrInvalidVerificationFunction , fmt . Sprintf ( "signer %d has no verification script and no deployed contract" , i ) )
2022-08-22 15:50:35 +00:00
}
md := cs . Manifest . ABI . GetMethod ( manifest . MethodVerify , - 1 )
if md == nil || md . ReturnType != smartcontract . BoolType {
2023-08-14 16:43:19 +00:00
return 0 , neorpc . WrapErrorWithData ( neorpc . ErrInvalidVerificationFunction , fmt . Sprintf ( "signer %d has no verify method in deployed contract" , i ) )
2022-08-22 15:50:35 +00:00
}
paramz = md . Parameters // Might as well have none params and it's OK.
} else { // Regular signature verification.
if vm . IsSignatureContract ( w . VerificationScript ) {
paramz = [ ] manifest . Parameter { { Type : smartcontract . SignatureType } }
} else if nSigs , _ , ok := vm . ParseMultiSigContract ( w . VerificationScript ) ; ok {
paramz = make ( [ ] manifest . Parameter , nSigs )
2024-08-30 18:41:02 +00:00
for j := range paramz {
2022-08-22 15:50:35 +00:00
paramz [ j ] = manifest . Parameter { Type : smartcontract . SignatureType }
}
}
}
inv := io . NewBufBinWriter ( )
for _ , p := range paramz {
p . Type . EncodeDefaultValue ( inv . BinWriter )
}
if inv . Err != nil {
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to create dummy invocation script (signer %d): %s" , i , inv . Err . Error ( ) ) )
}
w . InvocationScript = inv . Bytes ( )
2021-03-24 17:32:48 +00:00
}
2023-09-27 16:31:21 +00:00
gasConsumed , err := s . chain . VerifyWitness ( signer . Account , tx , & w , gasLimit )
2023-09-27 16:24:45 +00:00
if err != nil && ! errors . Is ( err , core . ErrInvalidSignature ) {
2024-07-11 09:03:34 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidSignature , fmt . Sprintf ( "witness %d: %s" , i , err ) )
2023-09-27 16:24:45 +00:00
}
2023-09-27 16:31:21 +00:00
gasLimit -= gasConsumed
2022-08-22 15:50:35 +00:00
netFee += gasConsumed
size += io . GetVarSize ( w . VerificationScript ) + io . GetVarSize ( w . InvocationScript )
2021-03-24 17:32:48 +00:00
}
2023-09-21 15:22:32 +00:00
netFee += int64 ( size ) * s . chain . FeePerByte ( ) + s . chain . CalculateAttributesFee ( tx )
2021-06-04 17:44:58 +00:00
return result . NetworkFee { Value : netFee } , nil
2021-03-24 17:32:48 +00:00
}
2020-09-21 11:08:15 +00:00
// getApplicationLog returns the contract log based on the specified txid or blockid.
2023-04-03 10:34:24 +00:00
func ( s * Server ) getApplicationLog ( reqParams params . Params ) ( any , * neorpc . Error ) {
2020-09-21 11:08:15 +00:00
hash , err := reqParams . Value ( 0 ) . GetUint256 ( )
2020-02-21 14:56:28 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-02-21 14:56:28 +00:00
}
2020-11-10 11:30:00 +00:00
trig := trigger . All
if len ( reqParams ) > 1 {
2021-10-28 11:10:18 +00:00
trigString , err := reqParams . Value ( 1 ) . GetString ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
rpc: fix `getapplicationlog` RPC handler
Fixes the following panic:
```
2020/12/22 18:16:09 http: panic serving 127.0.0.1:50228: runtime error: invalid memory address or nil pointer dereference
goroutine 4043 [running]:
net/http.(*conn).serve.func1(0xc00094c960)
net/http/server.go:1772 +0x139
panic(0xcd9b40, 0x16a94e0)
runtime/panic.go:973 +0x396
github.com/nspcc-dev/neo-go/pkg/rpc/server.(*Server).getApplicationLog(0xc000094ea0, 0xc000472d20, 0x2, 0x4, 0xc0000be228, 0xc0007ad601, 0x28)
github.com/nspcc-dev/neo-go/pkg/rpc/server/server.go:542 +0xac
github.com/nspcc-dev/neo-go/pkg/rpc/server.(*Server).handleIn(0xc000094ea0, 0xc000089770, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
github.com/nspcc-dev/neo-go/pkg/rpc/server/server.go:326 +0x981
github.com/nspcc-dev/neo-go/pkg/rpc/server.(*Server).handleRequest(0xc000094ea0, 0xc001bccba0, 0x0, 0x0, 0x0)
github.com/nspcc-dev/neo-go/pkg/rpc/server/server.go:296 +0x26a
github.com/nspcc-dev/neo-go/pkg/rpc/server.(*Server).handleHTTPRequest(0xc000094ea0, 0x1071f40, 0xc000b089a0, 0xc00053c200)
github.com/nspcc-dev/neo-go/pkg/rpc/server/server.go:290 +0x91b
net/http.HandlerFunc.ServeHTTP(0xc0004e61b0, 0x1071f40, 0xc000b089a0, 0xc00053c200)
net/http/server.go:2012 +0x44
net/http.serverHandler.ServeHTTP(0xc0000d2ee0, 0x1071f40, 0xc000b089a0, 0xc00053c200)
net/http/server.go:2807 +0xa3
net/http.(*conn).serve(0xc00094c960, 0x10749c0, 0xc0006ae980)
net/http/server.go:1895 +0x86c
created by net/http.(*Server).Serve
net/http/server.go:2933 +0x35c
```
2020-12-22 15:21:04 +00:00
}
2021-10-28 11:10:18 +00:00
trig , err = trigger . FromString ( trigString )
2020-11-10 11:30:00 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-11-10 11:30:00 +00:00
}
}
2020-11-11 15:43:28 +00:00
appExecResults , err := s . chain . GetAppExecResults ( hash , trigger . All )
2020-02-21 14:56:28 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrUnknownScriptContainer , fmt . Sprintf ( "failed to locate application log: %s" , err ) )
2020-02-21 14:56:28 +00:00
}
2020-11-10 11:30:00 +00:00
return result . NewApplicationLog ( hash , appExecResults , trig ) , nil
2020-02-21 14:56:28 +00:00
}
2022-07-04 14:12:42 +00:00
func ( s * Server ) getNEP11Tokens ( h util . Uint160 , acc util . Uint160 , bw * io . BufBinWriter ) ( [ ] stackitem . Item , string , int , error ) {
2023-04-03 10:34:24 +00:00
items , finalize , err := s . invokeReadOnlyMulti ( bw , h , [ ] string { "tokensOf" , "symbol" , "decimals" } , [ ] [ ] any { { acc } , nil , nil } )
2021-11-17 20:04:50 +00:00
if err != nil {
2022-07-04 14:12:42 +00:00
return nil , "" , 0 , err
2021-11-17 20:04:50 +00:00
}
defer finalize ( )
2022-07-04 14:12:42 +00:00
if ( items [ 0 ] . Type ( ) != stackitem . InteropT ) || ! iterator . IsIterator ( items [ 0 ] ) {
return nil , "" , 0 , fmt . Errorf ( "invalid `tokensOf` result type %s" , items [ 0 ] . String ( ) )
}
2022-06-15 18:23:29 +00:00
vals := iterator . Values ( items [ 0 ] , s . config . MaxNEP11Tokens )
2022-07-04 14:12:42 +00:00
sym , err := stackitem . ToString ( items [ 1 ] )
if err != nil {
return nil , "" , 0 , fmt . Errorf ( "`symbol` return value error: %w" , err )
2021-11-17 20:04:50 +00:00
}
2022-07-04 14:12:42 +00:00
dec , err := items [ 2 ] . TryInteger ( )
if err != nil {
return nil , "" , 0 , fmt . Errorf ( "`decimals` return value error: %w" , err )
}
if ! dec . IsInt64 ( ) || dec . Sign ( ) == - 1 || dec . Int64 ( ) > math . MaxInt32 {
return nil , "" , 0 , errors . New ( "`decimals` returned a bad integer" )
}
return vals , sym , int ( dec . Int64 ( ) ) , nil
2021-11-17 20:04:50 +00:00
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getNEP11Balances ( ps params . Params ) ( any , * neorpc . Error ) {
2021-11-17 20:04:50 +00:00
u , err := ps . Value ( 0 ) . GetUint160FromAddressOrHex ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2021-11-17 20:04:50 +00:00
}
bs := & result . NEP11Balances {
Address : address . Uint160ToString ( u ) ,
Balances : [ ] result . NEP11AssetBalance { } ,
}
lastUpdated , err := s . chain . GetTokenLastUpdated ( u )
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "Failed to get NEP-11 last updated block: %s" , err . Error ( ) ) )
2021-11-17 20:04:50 +00:00
}
var count int
stateSyncPoint := lastUpdated [ math . MinInt32 ]
bw := io . NewBufBinWriter ( )
contract_loop :
for _ , h := range s . chain . GetNEP11Contracts ( ) {
2022-07-04 14:12:42 +00:00
toks , sym , dec , err := s . getNEP11Tokens ( h , u , bw )
2021-11-17 20:04:50 +00:00
if err != nil {
continue
}
if len ( toks ) == 0 {
continue
}
cs := s . chain . GetContractState ( h )
if cs == nil {
continue
}
2022-12-10 08:35:03 +00:00
isDivisible := ( standard . ComplyABI ( & cs . Manifest , standard . Nep11Divisible ) == nil )
2021-11-17 20:04:50 +00:00
lub , ok := lastUpdated [ cs . ID ]
if ! ok {
cfg := s . chain . GetConfig ( )
2022-12-06 13:34:38 +00:00
if ! cfg . P2PStateExchangeExtensions && cfg . Ledger . RemoveUntraceableBlocks {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to get LastUpdatedBlock for balance of %s token: internal database inconsistency" , cs . Hash . StringLE ( ) ) )
2021-11-17 20:04:50 +00:00
}
lub = stateSyncPoint
}
bs . Balances = append ( bs . Balances , result . NEP11AssetBalance {
2022-07-04 14:12:42 +00:00
Asset : h ,
Decimals : dec ,
Name : cs . Manifest . Name ,
Symbol : sym ,
Tokens : make ( [ ] result . NEP11TokenBalance , 0 , len ( toks ) ) ,
2021-11-17 20:04:50 +00:00
} )
curAsset := & bs . Balances [ len ( bs . Balances ) - 1 ]
for i := range toks {
id , err := toks [ i ] . TryBytes ( )
2022-07-08 16:51:59 +00:00
if err != nil || len ( id ) > limits . MaxStorageKeyLen {
2021-11-17 20:04:50 +00:00
continue
}
var amount = "1"
if isDivisible {
2022-07-04 14:12:42 +00:00
balance , err := s . getNEP11DTokenBalance ( h , u , id , bw )
2021-11-17 20:04:50 +00:00
if err != nil {
continue
}
if balance . Sign ( ) == 0 {
continue
}
amount = balance . String ( )
}
count ++
curAsset . Tokens = append ( curAsset . Tokens , result . NEP11TokenBalance {
ID : hex . EncodeToString ( id ) ,
Amount : amount ,
LastUpdated : lub ,
} )
if count >= s . config . MaxNEP11Tokens {
break contract_loop
}
}
}
return bs , nil
}
func ( s * Server ) invokeNEP11Properties ( h util . Uint160 , id [ ] byte , bw * io . BufBinWriter ) ( [ ] stackitem . MapElement , error ) {
item , finalize , err := s . invokeReadOnly ( bw , h , "properties" , id )
if err != nil {
return nil , err
}
defer finalize ( )
if item . Type ( ) != stackitem . MapT {
return nil , fmt . Errorf ( "invalid `properties` result type %s" , item . String ( ) )
}
return item . Value ( ) . ( [ ] stackitem . MapElement ) , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getNEP11Properties ( ps params . Params ) ( any , * neorpc . Error ) {
2021-11-17 20:04:50 +00:00
asset , err := ps . Value ( 0 ) . GetUint160FromAddressOrHex ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2021-11-17 20:04:50 +00:00
}
token , err := ps . Value ( 1 ) . GetBytesHex ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2021-11-17 20:04:50 +00:00
}
props , err := s . invokeNEP11Properties ( asset , token , nil )
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrExecutionFailed , fmt . Sprintf ( "Failed to get NEP-11 properties: %s" , err . Error ( ) ) )
2021-11-17 20:04:50 +00:00
}
2023-04-03 10:34:24 +00:00
res := make ( map [ string ] any )
2021-11-17 20:04:50 +00:00
for _ , kv := range props {
key , err := kv . Key . TryBytes ( )
if err != nil {
continue
}
2023-04-03 10:34:24 +00:00
var val any
2021-11-17 21:08:10 +00:00
if result . KnownNEP11Properties [ string ( key ) ] || kv . Value . Type ( ) != stackitem . AnyT {
2021-11-17 20:04:50 +00:00
v , err := kv . Value . TryBytes ( )
if err != nil {
continue
}
2021-11-17 21:08:10 +00:00
if result . KnownNEP11Properties [ string ( key ) ] {
2021-11-17 20:04:50 +00:00
val = string ( v )
} else {
val = v
}
}
res [ string ( key ) ] = val
}
return res , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getNEP17Balances ( ps params . Params ) ( any , * neorpc . Error ) {
2020-07-03 15:10:07 +00:00
u , err := ps . Value ( 0 ) . GetUint160FromAddressOrHex ( )
2020-03-05 11:50:06 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-03-05 11:50:06 +00:00
}
2020-11-24 08:14:25 +00:00
bs := & result . NEP17Balances {
2020-03-11 12:03:20 +00:00
Address : address . Uint160ToString ( u ) ,
2020-11-24 08:14:25 +00:00
Balances : [ ] result . NEP17Balance { } ,
2020-03-11 12:03:20 +00:00
}
2021-11-16 20:09:04 +00:00
lastUpdated , err := s . chain . GetTokenLastUpdated ( u )
2021-07-25 12:00:44 +00:00
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "Failed to get NEP-17 last updated block: %s" , err . Error ( ) ) )
2021-07-25 12:00:44 +00:00
}
2021-08-11 11:29:03 +00:00
stateSyncPoint := lastUpdated [ math . MinInt32 ]
2021-07-25 12:00:44 +00:00
bw := io . NewBufBinWriter ( )
for _ , h := range s . chain . GetNEP17Contracts ( ) {
2022-07-04 14:12:42 +00:00
balance , sym , dec , err := s . getNEP17TokenBalance ( h , u , bw )
2021-07-25 12:00:44 +00:00
if err != nil {
continue
}
if balance . Sign ( ) == 0 {
continue
}
cs := s . chain . GetContractState ( h )
if cs == nil {
continue
2020-03-05 11:50:06 +00:00
}
2021-08-11 11:29:03 +00:00
lub , ok := lastUpdated [ cs . ID ]
if ! ok {
cfg := s . chain . GetConfig ( )
2022-12-06 13:34:38 +00:00
if ! cfg . P2PStateExchangeExtensions && cfg . Ledger . RemoveUntraceableBlocks {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to get LastUpdatedBlock for balance of %s token: internal database inconsistency" , cs . Hash . StringLE ( ) ) )
2021-08-11 11:29:03 +00:00
}
lub = stateSyncPoint
}
2021-07-25 12:00:44 +00:00
bs . Balances = append ( bs . Balances , result . NEP17Balance {
Asset : h ,
Amount : balance . String ( ) ,
2022-07-04 14:12:42 +00:00
Decimals : dec ,
2021-08-11 11:29:03 +00:00
LastUpdated : lub ,
2022-07-04 14:12:42 +00:00
Name : cs . Manifest . Name ,
Symbol : sym ,
2021-07-25 12:00:44 +00:00
} )
2020-03-05 11:50:06 +00:00
}
return bs , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) invokeReadOnly ( bw * io . BufBinWriter , h util . Uint160 , method string , params ... any ) ( stackitem . Item , func ( ) , error ) {
r , f , err := s . invokeReadOnlyMulti ( bw , h , [ ] string { method } , [ ] [ ] any { params } )
2022-07-04 14:12:42 +00:00
if err != nil {
return nil , nil , err
}
return r [ 0 ] , f , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) invokeReadOnlyMulti ( bw * io . BufBinWriter , h util . Uint160 , methods [ ] string , params [ ] [ ] any ) ( [ ] stackitem . Item , func ( ) , error ) {
2021-07-25 12:00:44 +00:00
if bw == nil {
bw = io . NewBufBinWriter ( )
} else {
bw . Reset ( )
}
2022-07-04 14:12:42 +00:00
if len ( methods ) != len ( params ) {
return nil , nil , fmt . Errorf ( "asymmetric parameters" )
}
for i := range methods {
emit . AppCall ( bw . BinWriter , h , methods [ i ] , callflag . ReadStates | callflag . AllowCall , params [ i ] ... )
if bw . Err != nil {
return nil , nil , fmt . Errorf ( "failed to create `%s` invocation script: %w" , methods [ i ] , bw . Err )
}
2021-07-25 12:00:44 +00:00
}
script := bw . Bytes ( )
tx := & transaction . Transaction { Script : script }
2022-10-06 10:24:57 +00:00
ic , err := s . chain . GetTestVM ( trigger . Application , tx , nil )
2021-11-17 20:04:50 +00:00
if err != nil {
2022-10-06 10:24:57 +00:00
return nil , nil , fmt . Errorf ( "faile to prepare test VM: %w" , err )
2021-11-17 20:04:50 +00:00
}
2022-01-12 22:20:08 +00:00
ic . VM . GasLimit = core . HeaderVerificationGasLimit
ic . VM . LoadScriptWithFlags ( script , callflag . All )
err = ic . VM . Run ( )
2021-07-25 12:00:44 +00:00
if err != nil {
2022-01-12 22:20:08 +00:00
ic . Finalize ( )
2022-07-04 14:12:42 +00:00
return nil , nil , fmt . Errorf ( "failed to run %d methods of %s: %w" , len ( methods ) , h . StringLE ( ) , err )
2021-07-25 12:00:44 +00:00
}
2022-07-04 14:12:42 +00:00
estack := ic . VM . Estack ( )
if estack . Len ( ) != len ( methods ) {
2022-01-12 22:20:08 +00:00
ic . Finalize ( )
2022-07-04 14:12:42 +00:00
return nil , nil , fmt . Errorf ( "invalid return values count: expected %d, got %d" , len ( methods ) , estack . Len ( ) )
2021-11-17 20:04:50 +00:00
}
2022-07-04 14:12:42 +00:00
return estack . ToArray ( ) , ic . Finalize , nil
2021-11-17 20:04:50 +00:00
}
2022-07-04 14:12:42 +00:00
func ( s * Server ) getNEP17TokenBalance ( h util . Uint160 , acc util . Uint160 , bw * io . BufBinWriter ) ( * big . Int , string , int , error ) {
2023-04-03 10:34:24 +00:00
items , finalize , err := s . invokeReadOnlyMulti ( bw , h , [ ] string { "balanceOf" , "symbol" , "decimals" } , [ ] [ ] any { { acc } , nil , nil } )
2022-07-04 14:12:42 +00:00
if err != nil {
return nil , "" , 0 , err
2021-11-17 20:04:50 +00:00
}
2022-07-04 14:12:42 +00:00
finalize ( )
res , err := items [ 0 ] . TryInteger ( )
if err != nil {
return nil , "" , 0 , fmt . Errorf ( "unexpected `balanceOf` result type: %w" , err )
}
sym , err := stackitem . ToString ( items [ 1 ] )
if err != nil {
return nil , "" , 0 , fmt . Errorf ( "`symbol` return value error: %w" , err )
}
dec , err := items [ 2 ] . TryInteger ( )
if err != nil {
return nil , "" , 0 , fmt . Errorf ( "`decimals` return value error: %w" , err )
}
if ! dec . IsInt64 ( ) || dec . Sign ( ) == - 1 || dec . Int64 ( ) > math . MaxInt32 {
return nil , "" , 0 , errors . New ( "`decimals` returned a bad integer" )
}
return res , sym , int ( dec . Int64 ( ) ) , nil
}
func ( s * Server ) getNEP11DTokenBalance ( h util . Uint160 , acc util . Uint160 , id [ ] byte , bw * io . BufBinWriter ) ( * big . Int , error ) {
item , finalize , err := s . invokeReadOnly ( bw , h , "balanceOf" , acc , id )
2021-11-17 20:04:50 +00:00
if err != nil {
return nil , err
2021-07-25 12:00:44 +00:00
}
2021-11-17 20:04:50 +00:00
finalize ( )
res , err := item . TryInteger ( )
2021-07-25 12:00:44 +00:00
if err != nil {
return nil , fmt . Errorf ( "unexpected `balanceOf` result type: %w" , err )
}
return res , nil
}
2022-07-07 14:41:01 +00:00
func getTimestampsAndLimit ( ps params . Params , index int ) ( uint64 , uint64 , int , int , error ) {
2020-08-07 06:42:44 +00:00
var start , end uint64
2020-09-12 21:12:45 +00:00
var limit , page int
2020-09-14 14:48:17 +00:00
limit = maxTransfersLimit
2020-09-12 21:12:45 +00:00
pStart , pEnd , pLimit , pPage := ps . Value ( index ) , ps . Value ( index + 1 ) , ps . Value ( index + 2 ) , ps . Value ( index + 3 )
if pPage != nil {
p , err := pPage . GetInt ( )
if err != nil {
return 0 , 0 , 0 , 0 , err
}
if p < 0 {
return 0 , 0 , 0 , 0 , errors . New ( "can't use negative page" )
}
page = p
}
2020-09-11 19:33:17 +00:00
if pLimit != nil {
l , err := pLimit . GetInt ( )
2020-08-07 06:42:44 +00:00
if err != nil {
2020-09-12 21:12:45 +00:00
return 0 , 0 , 0 , 0 , err
2020-08-07 06:42:44 +00:00
}
2020-09-11 19:33:17 +00:00
if l <= 0 {
2020-09-12 21:12:45 +00:00
return 0 , 0 , 0 , 0 , errors . New ( "can't use negative or zero limit" )
2020-09-11 19:33:17 +00:00
}
2020-09-14 14:48:17 +00:00
if l > maxTransfersLimit {
return 0 , 0 , 0 , 0 , errors . New ( "too big limit requested" )
}
2020-09-11 19:33:17 +00:00
limit = l
2020-08-07 06:42:44 +00:00
}
2020-09-11 19:33:17 +00:00
if pEnd != nil {
val , err := pEnd . GetInt ( )
2020-08-07 06:42:44 +00:00
if err != nil {
2020-09-12 21:12:45 +00:00
return 0 , 0 , 0 , 0 , err
2020-08-07 06:42:44 +00:00
}
end = uint64 ( val )
2020-09-11 19:33:17 +00:00
} else {
end = uint64 ( time . Now ( ) . Unix ( ) * 1000 )
2020-08-07 06:42:44 +00:00
}
2020-09-11 19:33:17 +00:00
if pStart != nil {
val , err := pStart . GetInt ( )
2020-09-08 09:56:52 +00:00
if err != nil {
2020-09-12 21:12:45 +00:00
return 0 , 0 , 0 , 0 , err
2020-09-08 09:56:52 +00:00
}
2020-09-11 19:33:17 +00:00
start = uint64 ( val )
} else {
start = uint64 ( time . Now ( ) . Add ( - time . Hour * 24 * 7 ) . Unix ( ) * 1000 )
2020-09-08 09:56:52 +00:00
}
2020-09-12 21:12:45 +00:00
return start , end , limit , page , nil
2020-08-07 06:42:44 +00:00
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getNEP11Transfers ( ps params . Params ) ( any , * neorpc . Error ) {
2021-11-17 20:04:50 +00:00
return s . getTokenTransfers ( ps , true )
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getNEP17Transfers ( ps params . Params ) ( any , * neorpc . Error ) {
2021-11-17 20:04:50 +00:00
return s . getTokenTransfers ( ps , false )
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getTokenTransfers ( ps params . Params , isNEP11 bool ) ( any , * neorpc . Error ) {
2020-07-03 15:25:18 +00:00
u , err := ps . Value ( 0 ) . GetUint160FromAddressOrHex ( )
2020-03-05 12:16:03 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-03-05 12:16:03 +00:00
}
2020-09-12 21:12:45 +00:00
start , end , limit , page , err := getTimestampsAndLimit ( ps , 1 )
2020-08-07 06:42:44 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "malformed timestamps/limit: %s" , err ) )
2020-08-07 06:42:44 +00:00
}
2021-11-17 20:04:50 +00:00
bs := & tokenTransfers {
2020-03-11 12:03:20 +00:00
Address : address . Uint160ToString ( u ) ,
2023-04-03 10:34:24 +00:00
Received : [ ] any { } ,
Sent : [ ] any { } ,
2020-03-11 12:03:20 +00:00
}
rpc: adjust NEP5 transfers amount JSON marshalling
This committ fixes the difference between Go and C# nodes:
Go:
```
{
"jsonrpc" : "2.0",
"result" : {
"received" : [
{
"blockindex" : 65,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"transfernotifyindex" : 0,
"timestamp" : 1605535020126,
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"amount" : "29999999",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
],
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : []
},
"id" : 1
}
```
C#:
```
{
"id" : 1,
"result" : {
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : [],
"received" : [
{
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"timestamp" : 1605535020126,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"blockindex" : 65,
"transfernotifyindex" : 0,
"amount" : "2999999900000000",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
]
},
"jsonrpc" : "2.0"
}
```
2020-11-17 09:28:28 +00:00
cache := make ( map [ int32 ] util . Uint160 )
2020-09-12 21:12:45 +00:00
var resCount , frameCount int
2022-04-20 18:30:09 +00:00
// handleTransfer returns items to be added into the received and sent arrays
2021-11-17 20:04:50 +00:00
// along with a continue flag and error.
var handleTransfer = func ( tr * state . NEP17Transfer ) ( * result . NEP17Transfer , * result . NEP17Transfer , bool , error ) {
var received , sent * result . NEP17Transfer
2022-04-20 18:30:09 +00:00
// Iterating from the newest to the oldest, not yet reached required
2020-09-12 21:12:45 +00:00
// time frame, continue looping.
2020-09-08 12:29:07 +00:00
if tr . Timestamp > end {
2021-11-17 20:04:50 +00:00
return nil , nil , true , nil
2020-09-08 12:29:07 +00:00
}
2022-04-20 18:30:09 +00:00
// Iterating from the newest to the oldest, moved past required
2020-09-12 21:12:45 +00:00
// time frame, stop looping.
if tr . Timestamp < start {
2021-11-17 20:04:50 +00:00
return nil , nil , false , nil
2020-08-07 06:42:44 +00:00
}
2020-09-12 21:12:45 +00:00
frameCount ++
// Using limits, not yet reached required page.
if limit != 0 && page * limit >= frameCount {
2021-11-17 20:04:50 +00:00
return nil , nil , true , nil
2020-09-12 21:12:45 +00:00
}
rpc: adjust NEP5 transfers amount JSON marshalling
This committ fixes the difference between Go and C# nodes:
Go:
```
{
"jsonrpc" : "2.0",
"result" : {
"received" : [
{
"blockindex" : 65,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"transfernotifyindex" : 0,
"timestamp" : 1605535020126,
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"amount" : "29999999",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
],
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : []
},
"id" : 1
}
```
C#:
```
{
"id" : 1,
"result" : {
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : [],
"received" : [
{
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"timestamp" : 1605535020126,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"blockindex" : 65,
"transfernotifyindex" : 0,
"amount" : "2999999900000000",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
]
},
"jsonrpc" : "2.0"
}
```
2020-11-17 09:28:28 +00:00
h , err := s . getHash ( tr . Asset , cache )
2020-07-28 16:05:16 +00:00
if err != nil {
2021-11-17 20:04:50 +00:00
return nil , nil , false , err
2020-07-28 16:05:16 +00:00
}
2020-09-12 21:12:45 +00:00
2020-11-24 08:14:25 +00:00
transfer := result . NEP17Transfer {
2020-03-05 12:16:03 +00:00
Timestamp : tr . Timestamp ,
rpc: adjust NEP5 transfers amount JSON marshalling
This committ fixes the difference between Go and C# nodes:
Go:
```
{
"jsonrpc" : "2.0",
"result" : {
"received" : [
{
"blockindex" : 65,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"transfernotifyindex" : 0,
"timestamp" : 1605535020126,
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"amount" : "29999999",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
],
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : []
},
"id" : 1
}
```
C#:
```
{
"id" : 1,
"result" : {
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : [],
"received" : [
{
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"timestamp" : 1605535020126,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"blockindex" : 65,
"transfernotifyindex" : 0,
"amount" : "2999999900000000",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
]
},
"jsonrpc" : "2.0"
}
```
2020-11-17 09:28:28 +00:00
Asset : h ,
2020-03-05 12:16:03 +00:00
Index : tr . Block ,
TxHash : tr . Tx ,
}
2023-01-10 19:37:44 +00:00
if ! tr . Counterparty . Equals ( util . Uint160 { } ) {
transfer . Address = address . Uint160ToString ( tr . Counterparty )
}
2020-07-09 09:57:24 +00:00
if tr . Amount . Sign ( ) > 0 { // token was received
rpc: adjust NEP5 transfers amount JSON marshalling
This committ fixes the difference between Go and C# nodes:
Go:
```
{
"jsonrpc" : "2.0",
"result" : {
"received" : [
{
"blockindex" : 65,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"transfernotifyindex" : 0,
"timestamp" : 1605535020126,
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"amount" : "29999999",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
],
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : []
},
"id" : 1
}
```
C#:
```
{
"id" : 1,
"result" : {
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : [],
"received" : [
{
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"timestamp" : 1605535020126,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"blockindex" : 65,
"transfernotifyindex" : 0,
"amount" : "2999999900000000",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
]
},
"jsonrpc" : "2.0"
}
```
2020-11-17 09:28:28 +00:00
transfer . Amount = tr . Amount . String ( )
2021-11-17 20:04:50 +00:00
received = & result . NEP17Transfer { }
* received = transfer // Make a copy, transfer is to be modified below.
2020-09-12 21:12:45 +00:00
} else {
2023-01-10 19:37:44 +00:00
transfer . Amount = new ( big . Int ) . Neg ( tr . Amount ) . String ( )
2021-11-17 20:04:50 +00:00
sent = & result . NEP17Transfer { }
* sent = transfer
2020-03-05 12:16:03 +00:00
}
2020-09-12 21:12:45 +00:00
resCount ++
2021-11-17 20:04:50 +00:00
// Check limits for continue flag.
return received , sent , ! ( limit != 0 && resCount >= limit ) , nil
}
if ! isNEP11 {
2022-01-18 15:28:24 +00:00
err = s . chain . ForEachNEP17Transfer ( u , end , func ( tr * state . NEP17Transfer ) ( bool , error ) {
2021-11-17 20:04:50 +00:00
r , s , res , err := handleTransfer ( tr )
if err == nil {
if r != nil {
bs . Received = append ( bs . Received , r )
}
if s != nil {
bs . Sent = append ( bs . Sent , s )
}
}
return res , err
} )
} else {
2022-01-18 15:28:24 +00:00
err = s . chain . ForEachNEP11Transfer ( u , end , func ( tr * state . NEP11Transfer ) ( bool , error ) {
2021-11-17 20:04:50 +00:00
r , s , res , err := handleTransfer ( & tr . NEP17Transfer )
if err == nil {
id := hex . EncodeToString ( tr . ID )
if r != nil {
bs . Received = append ( bs . Received , nep17TransferToNEP11 ( r , id ) )
}
if s != nil {
bs . Sent = append ( bs . Sent , nep17TransferToNEP11 ( s , id ) )
}
}
return res , err
} )
}
2020-03-05 12:16:03 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "invalid transfer log: %s" , err ) )
2020-03-05 12:16:03 +00:00
}
return bs , nil
}
rpc: adjust NEP5 transfers amount JSON marshalling
This committ fixes the difference between Go and C# nodes:
Go:
```
{
"jsonrpc" : "2.0",
"result" : {
"received" : [
{
"blockindex" : 65,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"transfernotifyindex" : 0,
"timestamp" : 1605535020126,
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"amount" : "29999999",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
],
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : []
},
"id" : 1
}
```
C#:
```
{
"id" : 1,
"result" : {
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : [],
"received" : [
{
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"timestamp" : 1605535020126,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"blockindex" : 65,
"transfernotifyindex" : 0,
"amount" : "2999999900000000",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
]
},
"jsonrpc" : "2.0"
}
```
2020-11-17 09:28:28 +00:00
// getHash returns the hash of the contract by its ID using cache.
func ( s * Server ) getHash ( contractID int32 , cache map [ int32 ] util . Uint160 ) ( util . Uint160 , error ) {
2020-07-29 12:09:59 +00:00
if d , ok := cache [ contractID ] ; ok {
2020-03-05 12:39:53 +00:00
return d , nil
}
2020-07-29 12:09:59 +00:00
h , err := s . chain . GetContractScriptHash ( contractID )
if err != nil {
rpc: adjust NEP5 transfers amount JSON marshalling
This committ fixes the difference between Go and C# nodes:
Go:
```
{
"jsonrpc" : "2.0",
"result" : {
"received" : [
{
"blockindex" : 65,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"transfernotifyindex" : 0,
"timestamp" : 1605535020126,
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"amount" : "29999999",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
],
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : []
},
"id" : 1
}
```
C#:
```
{
"id" : 1,
"result" : {
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : [],
"received" : [
{
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"timestamp" : 1605535020126,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"blockindex" : 65,
"transfernotifyindex" : 0,
"amount" : "2999999900000000",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
]
},
"jsonrpc" : "2.0"
}
```
2020-11-17 09:28:28 +00:00
return util . Uint160 { } , err
2020-03-05 12:39:53 +00:00
}
rpc: adjust NEP5 transfers amount JSON marshalling
This committ fixes the difference between Go and C# nodes:
Go:
```
{
"jsonrpc" : "2.0",
"result" : {
"received" : [
{
"blockindex" : 65,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"transfernotifyindex" : 0,
"timestamp" : 1605535020126,
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"amount" : "29999999",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
],
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : []
},
"id" : 1
}
```
C#:
```
{
"id" : 1,
"result" : {
"address" : "NULwe3UAHckN2fzNdcVg31tDiaYtMDwANt",
"sent" : [],
"received" : [
{
"transferaddress" : "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"timestamp" : 1605535020126,
"txhash" : "0x394f851cf167d664c0dbcf98e2e64f2da23022fd7943dcb914492529de20a945",
"blockindex" : 65,
"transfernotifyindex" : 0,
"amount" : "2999999900000000",
"assethash" : "0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc"
}
]
},
"jsonrpc" : "2.0"
}
```
2020-11-17 09:28:28 +00:00
cache [ contractID ] = h
return h , nil
2020-03-05 12:39:53 +00:00
}
2023-08-22 16:00:43 +00:00
func ( s * Server ) contractIDFromParam ( param * params . Param , root ... util . Uint256 ) ( int32 , * neorpc . Error ) {
2020-06-18 10:50:30 +00:00
var result int32
2020-06-04 11:58:47 +00:00
if param == nil {
2022-07-22 16:09:29 +00:00
return 0 , neorpc . ErrInvalidParams
2020-06-04 11:58:47 +00:00
}
2021-10-28 11:10:18 +00:00
if scriptHash , err := param . GetUint160FromHex ( ) ; err == nil {
2023-08-22 16:00:43 +00:00
if len ( root ) == 0 {
cs := s . chain . GetContractState ( scriptHash )
if cs == nil {
return 0 , neorpc . ErrUnknownContract
}
result = cs . ID
} else {
cs , respErr := s . getHistoricalContractState ( root [ 0 ] , scriptHash )
if respErr != nil {
return 0 , respErr
}
result = cs . ID
2020-06-18 10:50:30 +00:00
}
2021-10-28 11:10:18 +00:00
} else {
2020-06-18 10:50:30 +00:00
id , err := param . GetInt ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return 0 , neorpc . ErrInvalidParams
2020-06-18 10:50:30 +00:00
}
2021-04-19 07:48:35 +00:00
if err := checkInt32 ( id ) ; err != nil {
2022-07-22 16:09:29 +00:00
return 0 , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , err . Error ( ) )
2021-04-19 07:48:35 +00:00
}
2020-06-18 10:50:30 +00:00
result = int32 ( id )
}
return result , nil
}
2020-09-25 09:40:57 +00:00
// getContractScriptHashFromParam returns the contract script hash by hex contract hash, address, id or native contract name.
2022-07-22 16:09:29 +00:00
func ( s * Server ) contractScriptHashFromParam ( param * params . Param ) ( util . Uint160 , * neorpc . Error ) {
2020-09-25 09:40:57 +00:00
var result util . Uint160
if param == nil {
2022-07-22 16:09:29 +00:00
return result , neorpc . ErrInvalidParams
2020-09-25 09:40:57 +00:00
}
2021-10-29 14:06:45 +00:00
nameOrHashOrIndex , err := param . GetString ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return result , neorpc . ErrInvalidParams
2020-09-25 09:40:57 +00:00
}
2021-10-29 14:06:45 +00:00
result , err = param . GetUint160FromAddressOrHex ( )
if err == nil {
return result , nil
}
result , err = s . chain . GetNativeContractScriptHash ( nameOrHashOrIndex )
if err == nil {
return result , nil
}
id , err := strconv . Atoi ( nameOrHashOrIndex )
if err != nil {
2023-08-14 16:43:19 +00:00
return result , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "Invalid contract identifier (name/hash/index is expected) : %s" , err . Error ( ) ) )
2021-10-29 14:06:45 +00:00
}
if err := checkInt32 ( id ) ; err != nil {
2022-07-22 16:09:29 +00:00
return result , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , err . Error ( ) )
2021-10-29 14:06:45 +00:00
}
result , err = s . chain . GetContractScriptHash ( int32 ( id ) )
if err != nil {
2023-08-14 16:43:19 +00:00
return result , neorpc . ErrUnknownContract
2020-09-25 09:40:57 +00:00
}
return result , nil
}
2020-06-04 08:59:22 +00:00
func makeStorageKey ( id int32 , key [ ] byte ) [ ] byte {
skey := make ( [ ] byte , 4 + len ( key ) )
binary . LittleEndian . PutUint32 ( skey , uint32 ( id ) )
copy ( skey [ 4 : ] , key )
return skey
}
var errKeepOnlyLatestState = errors . New ( "'KeepOnlyLatestState' setting is enabled" )
2023-04-03 10:34:24 +00:00
func ( s * Server ) getProof ( ps params . Params ) ( any , * neorpc . Error ) {
2022-12-06 13:34:38 +00:00
if s . chain . GetConfig ( ) . Ledger . KeepOnlyLatestState {
2023-08-14 16:43:19 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrUnsupportedState , fmt . Sprintf ( "'getproof' is not supported: %s" , errKeepOnlyLatestState ) )
2020-06-04 08:59:22 +00:00
}
root , err := ps . Value ( 0 ) . GetUint256 ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-06-04 08:59:22 +00:00
}
sc , err := ps . Value ( 1 ) . GetUint160FromHex ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-06-04 08:59:22 +00:00
}
2021-03-30 10:08:13 +00:00
key , err := ps . Value ( 2 ) . GetBytesBase64 ( )
2020-06-04 08:59:22 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-06-04 08:59:22 +00:00
}
2021-10-15 04:01:47 +00:00
cs , respErr := s . getHistoricalContractState ( root , sc )
if respErr != nil {
return nil , respErr
2020-06-04 08:59:22 +00:00
}
skey := makeStorageKey ( cs . ID , key )
2021-01-29 14:33:24 +00:00
proof , err := s . chain . GetStateModule ( ) . GetStateProof ( root , skey )
2021-04-08 12:52:57 +00:00
if err != nil {
2023-08-14 16:43:19 +00:00
if errors . Is ( err , mpt . ErrNotFound ) {
return nil , neorpc . ErrUnknownStorageItem
}
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to get proof: %s" , err ) )
2021-04-08 12:52:57 +00:00
}
2021-03-30 10:08:13 +00:00
return & result . ProofWithKey {
Key : skey ,
Proof : proof ,
2020-06-04 08:59:22 +00:00
} , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) verifyProof ( ps params . Params ) ( any , * neorpc . Error ) {
2022-12-06 13:34:38 +00:00
if s . chain . GetConfig ( ) . Ledger . KeepOnlyLatestState {
2023-08-14 16:43:19 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrUnsupportedState , fmt . Sprintf ( "'verifyproof' is not supported: %s" , errKeepOnlyLatestState ) )
2020-06-05 08:51:39 +00:00
}
root , err := ps . Value ( 0 ) . GetUint256 ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-06-05 08:51:39 +00:00
}
proofStr , err := ps . Value ( 1 ) . GetString ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-06-05 08:51:39 +00:00
}
var p result . ProofWithKey
if err := p . FromString ( proofStr ) ; err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-06-05 08:51:39 +00:00
}
vp := new ( result . VerifyProof )
val , ok := mpt . VerifyProof ( root , p . Key , p . Proof )
2023-08-13 19:15:31 +00:00
if ! ok {
return nil , neorpc . ErrInvalidProof
2020-06-05 08:51:39 +00:00
}
2023-08-13 19:15:31 +00:00
vp . Value = val
2020-06-05 08:51:39 +00:00
return vp , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getState ( ps params . Params ) ( any , * neorpc . Error ) {
2023-08-22 16:00:43 +00:00
root , respErr := s . getStateRootFromParam ( ps . Value ( 0 ) )
if respErr != nil {
return nil , respErr
2021-10-07 09:03:37 +00:00
}
csHash , err := ps . Value ( 1 ) . GetUint160FromHex ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , "invalid contract hash" )
2021-10-07 09:03:37 +00:00
}
key , err := ps . Value ( 2 ) . GetBytesBase64 ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , "invalid key" )
2021-10-07 09:03:37 +00:00
}
2021-10-07 13:56:27 +00:00
cs , respErr := s . getHistoricalContractState ( root , csHash )
if respErr != nil {
return nil , respErr
}
sKey := makeStorageKey ( cs . ID , key )
res , err := s . chain . GetStateModule ( ) . GetState ( root , sKey )
if err != nil {
2023-08-14 16:43:19 +00:00
if errors . Is ( err , mpt . ErrNotFound ) {
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , fmt . Sprintf ( "invalid key: %s" , err . Error ( ) ) )
}
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "Failed to get historical item state: %s" , err . Error ( ) ) )
2021-10-07 13:56:27 +00:00
}
return res , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) findStates ( ps params . Params ) ( any , * neorpc . Error ) {
2023-08-22 16:00:43 +00:00
root , respErr := s . getStateRootFromParam ( ps . Value ( 0 ) )
if respErr != nil {
return nil , respErr
2021-10-07 13:56:27 +00:00
}
csHash , err := ps . Value ( 1 ) . GetUint160FromHex ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , fmt . Sprintf ( "invalid contract hash: %s" , err ) )
2021-10-07 13:56:27 +00:00
}
prefix , err := ps . Value ( 2 ) . GetBytesBase64 ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , fmt . Sprintf ( "invalid prefix: %s" , err ) )
2021-10-07 13:56:27 +00:00
}
var (
key [ ] byte
count = s . config . MaxFindResultItems
)
if len ( ps ) > 3 {
key , err = ps . Value ( 3 ) . GetBytesBase64 ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , fmt . Sprintf ( "invalid key: %s" , err ) )
2021-10-07 13:56:27 +00:00
}
2021-10-13 08:38:53 +00:00
if len ( key ) > 0 {
if ! bytes . HasPrefix ( key , prefix ) {
2022-07-22 16:09:29 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , "key doesn't match prefix" )
2021-10-13 08:38:53 +00:00
}
key = key [ len ( prefix ) : ]
} else {
// empty ("") key shouldn't exclude item matching prefix from the result
key = nil
}
2021-10-07 13:56:27 +00:00
}
if len ( ps ) > 4 {
count , err = ps . Value ( 4 ) . GetInt ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , fmt . Sprintf ( "invalid count: %s" , err ) )
2021-10-07 13:56:27 +00:00
}
2024-08-23 19:09:20 +00:00
count = min ( count , s . config . MaxFindResultItems )
2021-10-07 13:56:27 +00:00
}
cs , respErr := s . getHistoricalContractState ( root , csHash )
if respErr != nil {
return nil , respErr
}
pKey := makeStorageKey ( cs . ID , prefix )
2021-10-13 08:38:53 +00:00
kvs , err := s . chain . GetStateModule ( ) . FindStates ( root , pKey , key , count + 1 ) // +1 to define result truncation
2023-01-11 08:21:58 +00:00
if err != nil && ! errors . Is ( err , mpt . ErrNotFound ) {
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to find state items: %s" , err ) )
2021-10-07 13:56:27 +00:00
}
res := result . FindStates { }
if len ( kvs ) == count + 1 {
res . Truncated = true
kvs = kvs [ : len ( kvs ) - 1 ]
}
if len ( kvs ) > 0 {
proof , err := s . chain . GetStateModule ( ) . GetStateProof ( root , kvs [ 0 ] . Key )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to get first proof: %s" , err ) )
2021-10-07 13:56:27 +00:00
}
res . FirstProof = & result . ProofWithKey {
Key : kvs [ 0 ] . Key ,
Proof : proof ,
}
}
if len ( kvs ) > 1 {
proof , err := s . chain . GetStateModule ( ) . GetStateProof ( root , kvs [ len ( kvs ) - 1 ] . Key )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to get last proof: %s" , err ) )
2021-10-07 13:56:27 +00:00
}
res . LastProof = & result . ProofWithKey {
Key : kvs [ len ( kvs ) - 1 ] . Key ,
Proof : proof ,
}
}
res . Results = make ( [ ] result . KeyValue , len ( kvs ) )
for i , kv := range kvs {
res . Results [ i ] = result . KeyValue {
Key : kv . Key [ 4 : ] , // cut contract ID as it is done in C#
Value : kv . Value ,
}
}
return res , nil
}
2023-08-22 16:00:43 +00:00
// getStateRootFromParam retrieves state root hash from the provided parameter
// (only util.Uint256 serialized representation is allowed) and checks whether
// MPT states are supported for the old stateroot.
func ( s * Server ) getStateRootFromParam ( p * params . Param ) ( util . Uint256 , * neorpc . Error ) {
root , err := p . GetUint256 ( )
if err != nil {
return util . Uint256 { } , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , "invalid stateroot" )
}
if s . chain . GetConfig ( ) . Ledger . KeepOnlyLatestState {
curr , err := s . chain . GetStateModule ( ) . GetStateRoot ( s . chain . BlockHeight ( ) )
if err != nil {
return util . Uint256 { } , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to get current stateroot: %s" , err ) )
}
if ! curr . Root . Equals ( root ) {
return util . Uint256 { } , neorpc . WrapErrorWithData ( neorpc . ErrUnsupportedState , fmt . Sprintf ( "state-based methods are not supported for old states: %s" , errKeepOnlyLatestState ) )
}
}
return root , nil
}
func ( s * Server ) findStorage ( reqParams params . Params ) ( any , * neorpc . Error ) {
id , prefix , start , take , respErr := s . getFindStorageParams ( reqParams )
if respErr != nil {
return nil , respErr
}
2023-08-24 11:23:42 +00:00
return s . findStorageInternal ( id , prefix , start , take , s . chain )
}
func ( s * Server ) findStorageInternal ( id int32 , prefix [ ] byte , start , take int , seeker ContractStorageSeeker ) ( any , * neorpc . Error ) {
2023-08-22 16:00:43 +00:00
var (
i int
end = start + take
2024-04-01 12:14:13 +00:00
// Result is an empty list if a contract state is not found as it is in C# implementation.
res = & result . FindStorage { Results : make ( [ ] result . KeyValue , 0 ) }
2023-08-22 16:00:43 +00:00
)
2023-08-24 11:23:42 +00:00
seeker . SeekStorage ( id , prefix , func ( k , v [ ] byte ) bool {
2023-08-22 16:00:43 +00:00
if i < start {
i ++
return true
}
if i < end {
res . Results = append ( res . Results , result . KeyValue {
2024-03-04 18:09:36 +00:00
Key : bytes . Clone ( append ( prefix , k ... ) ) , // Don't strip prefix, as it is done in C#.
2023-08-22 16:00:43 +00:00
Value : v ,
} )
i ++
return true
}
res . Truncated = true
return false
} )
res . Next = i
return res , nil
}
func ( s * Server ) findStorageHistoric ( reqParams params . Params ) ( any , * neorpc . Error ) {
root , respErr := s . getStateRootFromParam ( reqParams . Value ( 0 ) )
if respErr != nil {
return nil , respErr
}
if len ( reqParams ) < 2 {
return nil , neorpc . ErrInvalidParams
}
id , prefix , start , take , respErr := s . getFindStorageParams ( reqParams [ 1 : ] , root )
if respErr != nil {
return nil , respErr
}
2023-08-24 11:23:42 +00:00
return s . findStorageInternal ( id , prefix , start , take , mptStorageSeeker {
root : root ,
module : s . chain . GetStateModule ( ) ,
} )
}
2023-08-22 16:00:43 +00:00
2023-08-24 11:23:42 +00:00
// mptStorageSeeker is an auxiliary structure that implements ContractStorageSeeker interface.
type mptStorageSeeker struct {
root util . Uint256
module core . StateRoot
}
func ( s mptStorageSeeker ) SeekStorage ( id int32 , prefix [ ] byte , cont func ( k , v [ ] byte ) bool ) {
key := makeStorageKey ( id , prefix )
s . module . SeekStates ( s . root , key , cont )
2023-08-22 16:00:43 +00:00
}
func ( s * Server ) getFindStorageParams ( reqParams params . Params , root ... util . Uint256 ) ( int32 , [ ] byte , int , int , * neorpc . Error ) {
if len ( reqParams ) < 2 {
return 0 , nil , 0 , 0 , neorpc . ErrInvalidParams
}
id , respErr := s . contractIDFromParam ( reqParams . Value ( 0 ) , root ... )
if respErr != nil {
return 0 , nil , 0 , 0 , respErr
}
prefix , err := reqParams . Value ( 1 ) . GetBytesBase64 ( )
if err != nil {
return 0 , nil , 0 , 0 , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , fmt . Sprintf ( "invalid prefix: %s" , err ) )
}
var skip int
if len ( reqParams ) > 2 {
skip , err = reqParams . Value ( 2 ) . GetInt ( )
if err != nil {
return 0 , nil , 0 , 0 , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , fmt . Sprintf ( "invalid start: %s" , err ) )
}
}
return id , prefix , skip , s . config . MaxFindStorageResultItems , nil
}
2022-07-22 16:09:29 +00:00
func ( s * Server ) getHistoricalContractState ( root util . Uint256 , csHash util . Uint160 ) ( * state . Contract , * neorpc . Error ) {
2021-10-07 09:03:37 +00:00
csKey := makeStorageKey ( native . ManagementContractID , native . MakeContractKey ( csHash ) )
csBytes , err := s . chain . GetStateModule ( ) . GetState ( root , csKey )
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrUnknownContract , fmt . Sprintf ( "Failed to get historical contract state: %s" , err . Error ( ) ) )
2021-10-07 09:03:37 +00:00
}
contract := new ( state . Contract )
err = stackitem . DeserializeConvertible ( csBytes , contract )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to deserialize historical contract state: %s" , err ) )
2021-10-07 09:03:37 +00:00
}
2021-10-07 13:56:27 +00:00
return contract , nil
2021-10-07 09:03:37 +00:00
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getStateHeight ( _ params . Params ) ( any , * neorpc . Error ) {
2020-06-04 08:09:07 +00:00
var height = s . chain . BlockHeight ( )
2021-02-01 16:00:07 +00:00
var stateHeight = s . chain . GetStateModule ( ) . CurrentValidatedHeight ( )
2020-06-04 08:09:07 +00:00
if s . chain . GetConfig ( ) . StateRootInHeader {
stateHeight = height - 1
}
return & result . StateHeight {
2021-07-22 16:55:41 +00:00
Local : height ,
Validated : stateHeight ,
2020-06-04 08:09:07 +00:00
} , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getStateRoot ( ps params . Params ) ( any , * neorpc . Error ) {
2020-06-03 15:09:36 +00:00
p := ps . Value ( 0 )
if p == nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( "missing stateroot identifier" )
2020-06-03 15:09:36 +00:00
}
2021-01-29 14:33:24 +00:00
var rt * state . MPTRoot
2020-06-03 15:09:36 +00:00
var h util . Uint256
2021-10-29 14:06:45 +00:00
height , err := p . GetIntStrict ( )
2020-06-03 15:09:36 +00:00
if err == nil {
2021-04-19 07:48:35 +00:00
if err := checkUint32 ( height ) ; err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , err . Error ( ) )
2021-04-19 07:48:35 +00:00
}
2021-01-29 14:33:24 +00:00
rt , err = s . chain . GetStateModule ( ) . GetStateRoot ( uint32 ( height ) )
2020-06-03 15:09:36 +00:00
} else if h , err = p . GetUint256 ( ) ; err == nil {
2020-12-28 14:31:50 +00:00
var hdr * block . Header
hdr , err = s . chain . GetHeader ( h )
2020-06-03 15:09:36 +00:00
if err == nil {
2021-01-29 14:33:24 +00:00
rt , err = s . chain . GetStateModule ( ) . GetStateRoot ( hdr . Index )
2020-06-03 15:09:36 +00:00
}
}
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrUnknownStateRoot
2020-06-03 15:09:36 +00:00
}
return rt , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getStorage ( ps params . Params ) ( any , * neorpc . Error ) {
2020-06-04 11:58:47 +00:00
id , rErr := s . contractIDFromParam ( ps . Value ( 0 ) )
2020-06-18 10:50:30 +00:00
if rErr != nil {
return nil , rErr
2020-01-30 08:03:44 +00:00
}
2021-02-07 15:27:19 +00:00
key , err := ps . Value ( 1 ) . GetBytesBase64 ( )
2020-01-30 08:03:44 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-01-30 08:03:44 +00:00
}
2020-06-18 10:50:30 +00:00
item := s . chain . GetStorageItem ( id , key )
2020-01-30 08:03:44 +00:00
if item == nil {
2023-08-11 21:56:15 +00:00
return "" , neorpc . ErrUnknownStorageItem
2020-01-30 08:03:44 +00:00
}
2021-03-05 14:06:54 +00:00
return [ ] byte ( item ) , nil
2020-01-30 08:03:44 +00:00
}
2023-08-22 16:29:22 +00:00
func ( s * Server ) getStorageHistoric ( ps params . Params ) ( any , * neorpc . Error ) {
root , respErr := s . getStateRootFromParam ( ps . Value ( 0 ) )
if respErr != nil {
return nil , respErr
}
if len ( ps ) < 2 {
return nil , neorpc . ErrInvalidParams
}
id , rErr := s . contractIDFromParam ( ps . Value ( 1 ) , root )
if rErr != nil {
return nil , rErr
}
key , err := ps . Value ( 2 ) . GetBytesBase64 ( )
if err != nil {
return nil , neorpc . ErrInvalidParams
}
pKey := makeStorageKey ( id , key )
v , err := s . chain . GetStateModule ( ) . GetState ( root , pKey )
if err != nil && ! errors . Is ( err , mpt . ErrNotFound ) {
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to get state item: %s" , err ) )
}
if v == nil {
return "" , neorpc . ErrUnknownStorageItem
}
return v , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getrawtransaction ( reqParams params . Params ) ( any , * neorpc . Error ) {
2020-11-13 13:54:38 +00:00
txHash , err := reqParams . Value ( 0 ) . GetUint256 ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-11-13 13:54:38 +00:00
}
tx , height , err := s . chain . GetTransaction ( txHash )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrUnknownTransaction
2020-11-13 13:54:38 +00:00
}
2021-10-28 11:10:18 +00:00
if v , _ := reqParams . Value ( 1 ) . GetBoolean ( ) ; v {
2022-07-08 11:32:29 +00:00
res := result . TransactionOutputRaw {
Transaction : * tx ,
}
if height == math . MaxUint32 { // Mempooled transaction.
return res , nil
2020-11-13 13:54:38 +00:00
}
2022-11-18 20:19:50 +00:00
_header := s . chain . GetHeaderHash ( height )
Implement rpc server method: sendrawtransaction (#174)
* Added new config attributes: 'SecondsPerBlock','LowPriorityThreshold'
* Added new files:
* Added new method: CompareTo
* Fixed empty Slice case
* Added new methods: LessThan, GreaterThan, Equal, CompareTo
* Added new method: InputIntersection
* Added MaxTransactionSize, GroupOutputByAssetID
* Added ned method: ScriptHash
* Added new method: IsDoubleSpend
* Refactor blockchainer, Added Feer interface, Verify and GetMemPool method
* 1) Added MemPool
2) Added new methods to satisfy the blockchainer interface: IsLowPriority, Verify, GetMemPool
* Added new methods: RelayTxn, RelayDirectly
* Fixed tests
* Implemented RPC server method sendrawtransaction
* Refactor getrawtransaction, sendrawtransaction in separate methods
* Moved 'secondsPerBlock' to config file
* Implemented Kim suggestions:
1) Fixed data race issues
2) refactor Verify method
3) Get rid of unused InputIntersection method due to refactoring Verify method
4) Fixed bug in https://github.com/CityOfZion/neo-go/pull/174#discussion_r264108135
5) minor simplications of the code
* Fixed minor issues related to
1) space
2) getter methods do not need pointer on the receiver
3) error message
4) refactoring CompareTo method in uint256.go
* Fixed small issues
* Use sync.RWMutex instead of sync.Mutex
* Refined (R)Lock/(R)Unlock
* return error instead of bool in Verify methods
2019-03-20 12:30:05 +00:00
header , err := s . chain . GetHeader ( _header )
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "Failed to get header for the transaction: %s" , err . Error ( ) ) )
Implement rpc server method: sendrawtransaction (#174)
* Added new config attributes: 'SecondsPerBlock','LowPriorityThreshold'
* Added new files:
* Added new method: CompareTo
* Fixed empty Slice case
* Added new methods: LessThan, GreaterThan, Equal, CompareTo
* Added new method: InputIntersection
* Added MaxTransactionSize, GroupOutputByAssetID
* Added ned method: ScriptHash
* Added new method: IsDoubleSpend
* Refactor blockchainer, Added Feer interface, Verify and GetMemPool method
* 1) Added MemPool
2) Added new methods to satisfy the blockchainer interface: IsLowPriority, Verify, GetMemPool
* Added new methods: RelayTxn, RelayDirectly
* Fixed tests
* Implemented RPC server method sendrawtransaction
* Refactor getrawtransaction, sendrawtransaction in separate methods
* Moved 'secondsPerBlock' to config file
* Implemented Kim suggestions:
1) Fixed data race issues
2) refactor Verify method
3) Get rid of unused InputIntersection method due to refactoring Verify method
4) Fixed bug in https://github.com/CityOfZion/neo-go/pull/174#discussion_r264108135
5) minor simplications of the code
* Fixed minor issues related to
1) space
2) getter methods do not need pointer on the receiver
3) error message
4) refactoring CompareTo method in uint256.go
* Fixed small issues
* Use sync.RWMutex instead of sync.Mutex
* Refined (R)Lock/(R)Unlock
* return error instead of bool in Verify methods
2019-03-20 12:30:05 +00:00
}
2020-11-11 15:43:28 +00:00
aers , err := s . chain . GetAppExecResults ( txHash , trigger . Application )
2020-07-27 15:07:05 +00:00
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "Failed to get application log for the transaction: %s" , err . Error ( ) ) )
2020-07-27 15:07:05 +00:00
}
2020-11-11 15:43:28 +00:00
if len ( aers ) == 0 {
2023-08-14 16:43:19 +00:00
return nil , neorpc . NewInternalServerError ( "Inconsistent application log: application log for the transaction is empty" )
2020-11-11 15:43:28 +00:00
}
2022-07-08 11:32:29 +00:00
res . TransactionMetadata = result . TransactionMetadata {
Blockhash : header . Hash ( ) ,
Confirmations : int ( s . chain . BlockHeight ( ) - header . Index + 1 ) ,
Timestamp : header . Timestamp ,
VMState : aers [ 0 ] . VMState . String ( ) ,
}
return res , nil
Implement rpc server method: sendrawtransaction (#174)
* Added new config attributes: 'SecondsPerBlock','LowPriorityThreshold'
* Added new files:
* Added new method: CompareTo
* Fixed empty Slice case
* Added new methods: LessThan, GreaterThan, Equal, CompareTo
* Added new method: InputIntersection
* Added MaxTransactionSize, GroupOutputByAssetID
* Added ned method: ScriptHash
* Added new method: IsDoubleSpend
* Refactor blockchainer, Added Feer interface, Verify and GetMemPool method
* 1) Added MemPool
2) Added new methods to satisfy the blockchainer interface: IsLowPriority, Verify, GetMemPool
* Added new methods: RelayTxn, RelayDirectly
* Fixed tests
* Implemented RPC server method sendrawtransaction
* Refactor getrawtransaction, sendrawtransaction in separate methods
* Moved 'secondsPerBlock' to config file
* Implemented Kim suggestions:
1) Fixed data race issues
2) refactor Verify method
3) Get rid of unused InputIntersection method due to refactoring Verify method
4) Fixed bug in https://github.com/CityOfZion/neo-go/pull/174#discussion_r264108135
5) minor simplications of the code
* Fixed minor issues related to
1) space
2) getter methods do not need pointer on the receiver
3) error message
4) refactoring CompareTo method in uint256.go
* Fixed small issues
* Use sync.RWMutex instead of sync.Mutex
* Refined (R)Lock/(R)Unlock
* return error instead of bool in Verify methods
2019-03-20 12:30:05 +00:00
}
2020-11-13 13:54:38 +00:00
return tx . Bytes ( ) , nil
Implement rpc server method: sendrawtransaction (#174)
* Added new config attributes: 'SecondsPerBlock','LowPriorityThreshold'
* Added new files:
* Added new method: CompareTo
* Fixed empty Slice case
* Added new methods: LessThan, GreaterThan, Equal, CompareTo
* Added new method: InputIntersection
* Added MaxTransactionSize, GroupOutputByAssetID
* Added ned method: ScriptHash
* Added new method: IsDoubleSpend
* Refactor blockchainer, Added Feer interface, Verify and GetMemPool method
* 1) Added MemPool
2) Added new methods to satisfy the blockchainer interface: IsLowPriority, Verify, GetMemPool
* Added new methods: RelayTxn, RelayDirectly
* Fixed tests
* Implemented RPC server method sendrawtransaction
* Refactor getrawtransaction, sendrawtransaction in separate methods
* Moved 'secondsPerBlock' to config file
* Implemented Kim suggestions:
1) Fixed data race issues
2) refactor Verify method
3) Get rid of unused InputIntersection method due to refactoring Verify method
4) Fixed bug in https://github.com/CityOfZion/neo-go/pull/174#discussion_r264108135
5) minor simplications of the code
* Fixed minor issues related to
1) space
2) getter methods do not need pointer on the receiver
3) error message
4) refactoring CompareTo method in uint256.go
* Fixed small issues
* Use sync.RWMutex instead of sync.Mutex
* Refined (R)Lock/(R)Unlock
* return error instead of bool in Verify methods
2019-03-20 12:30:05 +00:00
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getTransactionHeight ( ps params . Params ) ( any , * neorpc . Error ) {
2020-06-04 11:58:47 +00:00
h , err := ps . Value ( 0 ) . GetUint256 ( )
2020-03-05 14:20:50 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-03-05 14:20:50 +00:00
}
_ , height , err := s . chain . GetTransaction ( h )
2020-11-13 13:54:38 +00:00
if err != nil || height == math . MaxUint32 {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrUnknownTransaction
2020-03-05 14:20:50 +00:00
}
return height , nil
}
2020-09-25 09:40:57 +00:00
// getContractState returns contract state (contract information, according to the contract script hash,
// contract id or native contract name).
2023-04-03 10:34:24 +00:00
func ( s * Server ) getContractState ( reqParams params . Params ) ( any , * neorpc . Error ) {
2020-09-25 09:40:57 +00:00
scriptHash , err := s . contractScriptHashFromParam ( reqParams . Value ( 0 ) )
2020-06-04 11:58:47 +00:00
if err != nil {
2020-09-25 09:40:57 +00:00
return nil , err
2020-02-15 16:53:08 +00:00
}
2020-06-04 11:58:47 +00:00
cs := s . chain . GetContractState ( scriptHash )
if cs == nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . ErrUnknownContract
2020-06-04 11:58:47 +00:00
}
return cs , nil
2020-02-15 16:53:08 +00:00
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) getNativeContracts ( _ params . Params ) ( any , * neorpc . Error ) {
2021-02-09 09:25:38 +00:00
return s . chain . GetNatives ( ) , nil
}
2020-02-19 09:44:31 +00:00
// getBlockSysFee returns the system fees of the block, based on the specified index.
2023-04-03 10:34:24 +00:00
func ( s * Server ) getBlockSysFee ( reqParams params . Params ) ( any , * neorpc . Error ) {
2021-10-28 11:10:18 +00:00
num , err := s . blockHeightFromParam ( reqParams . Value ( 0 ) )
2020-02-19 09:44:31 +00:00
if err != nil {
2023-08-14 16:43:19 +00:00
return 0 , neorpc . WrapErrorWithData ( err , fmt . Sprintf ( "invalid block height: %s" , err . Data ) )
2020-02-19 09:44:31 +00:00
}
headerHash := s . chain . GetHeaderHash ( num )
2020-04-28 19:35:19 +00:00
block , errBlock := s . chain . GetBlock ( headerHash )
if errBlock != nil {
2022-07-22 16:09:29 +00:00
return 0 , neorpc . ErrUnknownBlock
2020-02-19 09:44:31 +00:00
}
2020-06-23 14:15:35 +00:00
var blockSysFee int64
2020-02-19 09:44:31 +00:00
for _ , tx := range block . Transactions {
2020-05-08 17:54:24 +00:00
blockSysFee += tx . SystemFee
2020-02-19 09:44:31 +00:00
}
return blockSysFee , nil
}
2020-03-04 17:35:37 +00:00
// getBlockHeader returns the corresponding block header information according to the specified script hash.
2023-04-03 10:34:24 +00:00
func ( s * Server ) getBlockHeader ( reqParams params . Params ) ( any , * neorpc . Error ) {
2020-06-04 11:58:47 +00:00
param := reqParams . Value ( 0 )
2020-06-05 13:02:55 +00:00
hash , respErr := s . blockHashFromParam ( param )
if respErr != nil {
return nil , respErr
2020-03-04 17:35:37 +00:00
}
2021-10-28 11:10:18 +00:00
verbose , _ := reqParams . Value ( 1 ) . GetBoolean ( )
2020-03-04 17:35:37 +00:00
h , err := s . chain . GetHeader ( hash )
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . ErrUnknownBlock
2020-03-04 17:35:37 +00:00
}
if verbose {
2022-07-08 11:50:00 +00:00
res := result . Header {
Header : * h ,
BlockMetadata : s . fillBlockMetadata ( h , h ) ,
}
return res , nil
2020-03-04 17:35:37 +00:00
}
buf := io . NewBufBinWriter ( )
h . EncodeBinary ( buf . BinWriter )
if buf . Err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "encoding error: %s" , buf . Err ) )
2020-03-04 17:35:37 +00:00
}
2020-11-06 14:37:58 +00:00
return buf . Bytes ( ) , nil
2020-03-04 17:35:37 +00:00
}
2020-06-01 20:27:03 +00:00
// getUnclaimedGas returns unclaimed GAS amount of the specified address.
2023-04-03 10:34:24 +00:00
func ( s * Server ) getUnclaimedGas ( ps params . Params ) ( any , * neorpc . Error ) {
2021-10-28 11:10:18 +00:00
u , err := ps . Value ( 0 ) . GetUint160FromAddressOrHex ( )
2020-03-06 17:38:17 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-03-06 17:38:17 +00:00
}
2020-11-06 09:27:05 +00:00
neo , _ := s . chain . GetGoverningTokenBalance ( u )
2020-07-09 09:57:24 +00:00
if neo . Sign ( ) == 0 {
2020-07-09 14:25:26 +00:00
return result . UnclaimedGas {
Address : u ,
} , nil
2020-03-06 17:38:17 +00:00
}
2020-11-06 09:27:05 +00:00
gas , err := s . chain . CalculateClaimable ( u , s . chain . BlockHeight ( ) + 1 ) // +1 as in C#, for the next block.
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "Can't calculate claimable: %s" , err . Error ( ) ) )
2020-11-06 09:27:05 +00:00
}
2020-07-09 14:25:26 +00:00
return result . UnclaimedGas {
Address : u ,
Unclaimed : * gas ,
} , nil
2020-03-06 17:38:17 +00:00
}
2022-07-01 13:02:03 +00:00
// getCandidates returns the current list of candidates with their active/inactive voting status.
2023-04-03 10:34:24 +00:00
func ( s * Server ) getCandidates ( _ params . Params ) ( any , * neorpc . Error ) {
2022-07-01 13:02:03 +00:00
var validators keys . PublicKeys
validators , err := s . chain . GetNextBlockValidators ( )
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "Can't get next block validators: %s" , err . Error ( ) ) )
2022-07-01 13:02:03 +00:00
}
enrollments , err := s . chain . GetEnrollments ( )
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "Can't get enrollments: %s" , err . Error ( ) ) )
2022-07-01 13:02:03 +00:00
}
2024-08-24 12:30:39 +00:00
var res = make ( [ ] result . Candidate , 0 , len ( enrollments ) )
2022-07-01 13:02:03 +00:00
for _ , v := range enrollments {
res = append ( res , result . Candidate {
PublicKey : * v . Key ,
Votes : v . Votes . Int64 ( ) ,
Active : validators . Contains ( v . Key ) ,
} )
}
return res , nil
}
2020-10-01 12:26:54 +00:00
// getNextBlockValidators returns validators for the next block with voting status.
2023-04-03 10:34:24 +00:00
func ( s * Server ) getNextBlockValidators ( _ params . Params ) ( any , * neorpc . Error ) {
2020-03-05 14:48:30 +00:00
var validators keys . PublicKeys
2020-10-01 12:26:54 +00:00
validators , err := s . chain . GetNextBlockValidators ( )
2020-03-05 14:48:30 +00:00
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "Can't get next block validators: %s" , err . Error ( ) ) )
2020-03-05 14:48:30 +00:00
}
enrollments , err := s . chain . GetEnrollments ( )
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "Can't get enrollments: %s" , err . Error ( ) ) )
2020-03-05 14:48:30 +00:00
}
2024-08-24 12:30:39 +00:00
var res = make ( [ ] result . Validator , 0 , len ( validators ) )
2020-03-05 14:48:30 +00:00
for _ , v := range enrollments {
2022-07-01 09:34:43 +00:00
if ! validators . Contains ( v . Key ) {
continue
}
2020-03-05 14:48:30 +00:00
res = append ( res , result . Validator {
2020-04-26 17:04:16 +00:00
PublicKey : * v . Key ,
Votes : v . Votes . Int64 ( ) ,
2020-03-05 14:48:30 +00:00
} )
}
return res , nil
}
2021-05-12 20:17:03 +00:00
// getCommittee returns the current list of NEO committee members.
2023-04-03 10:34:24 +00:00
func ( s * Server ) getCommittee ( _ params . Params ) ( any , * neorpc . Error ) {
2020-09-21 12:34:04 +00:00
keys , err := s . chain . GetCommittee ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "can't get committee members: %s" , err ) )
2020-09-21 12:34:04 +00:00
}
return keys , nil
}
2020-06-10 08:53:11 +00:00
// invokeFunction implements the `invokeFunction` RPC call.
2023-04-03 10:34:24 +00:00
func ( s * Server ) invokeFunction ( reqParams params . Params ) ( any , * neorpc . Error ) {
2022-04-07 15:13:08 +00:00
tx , verbose , respErr := s . getInvokeFunctionParams ( reqParams )
if respErr != nil {
return nil , respErr
}
return s . runScriptInVM ( trigger . Application , tx . Script , util . Uint160 { } , tx , nil , verbose )
}
// invokeFunctionHistoric implements the `invokeFunctionHistoric` RPC call.
2023-04-03 10:34:24 +00:00
func ( s * Server ) invokeFunctionHistoric ( reqParams params . Params ) ( any , * neorpc . Error ) {
2022-10-06 10:24:57 +00:00
nextH , respErr := s . getHistoricParams ( reqParams )
2022-04-07 15:13:08 +00:00
if respErr != nil {
return nil , respErr
}
2021-11-20 16:25:42 +00:00
if len ( reqParams ) < 2 {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2021-11-20 16:25:42 +00:00
}
2022-04-07 15:13:08 +00:00
tx , verbose , respErr := s . getInvokeFunctionParams ( reqParams [ 1 : ] )
if respErr != nil {
return nil , respErr
}
2022-10-06 10:24:57 +00:00
return s . runScriptInVM ( trigger . Application , tx . Script , util . Uint160 { } , tx , & nextH , verbose )
2022-04-07 15:13:08 +00:00
}
2022-07-22 16:09:29 +00:00
func ( s * Server ) getInvokeFunctionParams ( reqParams params . Params ) ( * transaction . Transaction , bool , * neorpc . Error ) {
2022-04-07 15:13:08 +00:00
if len ( reqParams ) < 2 {
2022-07-22 16:09:29 +00:00
return nil , false , neorpc . ErrInvalidParams
2022-04-07 15:13:08 +00:00
}
2020-09-25 15:43:47 +00:00
scriptHash , responseErr := s . contractScriptHashFromParam ( reqParams . Value ( 0 ) )
if responseErr != nil {
2022-04-07 15:13:08 +00:00
return nil , false , responseErr
2019-11-26 10:13:17 +00:00
}
2021-11-20 16:25:42 +00:00
method , err := reqParams [ 1 ] . GetString ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , false , neorpc . ErrInvalidParams
2021-11-20 16:25:42 +00:00
}
2022-07-07 14:41:01 +00:00
var invparams * params . Param
2021-11-20 16:25:42 +00:00
if len ( reqParams ) > 2 {
2022-07-07 14:41:01 +00:00
invparams = & reqParams [ 2 ]
2021-11-20 16:25:42 +00:00
}
2020-06-10 11:45:55 +00:00
tx := & transaction . Transaction { }
2021-11-20 16:25:42 +00:00
if len ( reqParams ) > 3 {
2020-12-14 12:23:39 +00:00
signers , _ , err := reqParams [ 3 ] . GetSignersWithWitnesses ( )
2020-06-10 11:45:55 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , false , neorpc . ErrInvalidParams
2020-06-10 11:45:55 +00:00
}
2020-07-29 16:57:38 +00:00
tx . Signers = signers
2020-06-10 11:45:55 +00:00
}
2021-11-20 18:55:55 +00:00
var verbose bool
if len ( reqParams ) > 4 {
verbose , err = reqParams [ 4 ] . GetBoolean ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , false , neorpc . ErrInvalidParams
2021-11-20 18:55:55 +00:00
}
}
2020-07-29 16:57:38 +00:00
if len ( tx . Signers ) == 0 {
2020-10-01 12:26:51 +00:00
tx . Signers = [ ] transaction . Signer { { Account : util . Uint160 { } , Scopes : transaction . None } }
2020-07-29 16:57:38 +00:00
}
2022-07-07 14:41:01 +00:00
script , err := params . CreateFunctionInvocationScript ( scriptHash , method , invparams )
2019-11-26 10:13:17 +00:00
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , false , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , fmt . Sprintf ( "can't create invocation script: %s" , err ) )
2019-11-26 10:13:17 +00:00
}
2020-07-14 14:32:59 +00:00
tx . Script = script
2022-04-07 15:13:08 +00:00
return tx , verbose , nil
2019-11-26 10:13:17 +00:00
}
2019-10-29 15:31:39 +00:00
// invokescript implements the `invokescript` RPC call.
2023-04-03 10:34:24 +00:00
func ( s * Server ) invokescript ( reqParams params . Params ) ( any , * neorpc . Error ) {
2022-04-07 15:13:08 +00:00
tx , verbose , respErr := s . getInvokeScriptParams ( reqParams )
if respErr != nil {
return nil , respErr
}
return s . runScriptInVM ( trigger . Application , tx . Script , util . Uint160 { } , tx , nil , verbose )
}
// invokescripthistoric implements the `invokescripthistoric` RPC call.
2023-04-03 10:34:24 +00:00
func ( s * Server ) invokescripthistoric ( reqParams params . Params ) ( any , * neorpc . Error ) {
2022-10-06 10:24:57 +00:00
nextH , respErr := s . getHistoricParams ( reqParams )
2022-04-07 15:13:08 +00:00
if respErr != nil {
return nil , respErr
}
if len ( reqParams ) < 2 {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2019-10-29 15:31:39 +00:00
}
2022-04-07 15:13:08 +00:00
tx , verbose , respErr := s . getInvokeScriptParams ( reqParams [ 1 : ] )
if respErr != nil {
return nil , respErr
}
2022-10-06 10:24:57 +00:00
return s . runScriptInVM ( trigger . Application , tx . Script , util . Uint160 { } , tx , & nextH , verbose )
2022-04-07 15:13:08 +00:00
}
2019-11-21 14:42:02 +00:00
2022-07-22 16:09:29 +00:00
func ( s * Server ) getInvokeScriptParams ( reqParams params . Params ) ( * transaction . Transaction , bool , * neorpc . Error ) {
2022-04-07 15:13:08 +00:00
script , err := reqParams . Value ( 0 ) . GetBytesBase64 ( )
2019-10-29 15:31:39 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , false , neorpc . ErrInvalidParams
2019-10-29 15:31:39 +00:00
}
2019-11-21 14:42:02 +00:00
2020-06-10 11:45:55 +00:00
tx := & transaction . Transaction { }
if len ( reqParams ) > 1 {
2021-09-09 14:26:53 +00:00
signers , witnesses , err := reqParams [ 1 ] . GetSignersWithWitnesses ( )
2020-06-10 11:45:55 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , false , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , err . Error ( ) )
2020-06-10 11:45:55 +00:00
}
2020-07-29 16:57:38 +00:00
tx . Signers = signers
2021-09-09 14:26:53 +00:00
tx . Scripts = witnesses
2020-07-29 16:57:38 +00:00
}
2021-11-20 18:55:55 +00:00
var verbose bool
if len ( reqParams ) > 2 {
verbose , err = reqParams [ 2 ] . GetBoolean ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , false , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , err . Error ( ) )
2021-11-20 18:55:55 +00:00
}
}
2020-07-29 16:57:38 +00:00
if len ( tx . Signers ) == 0 {
2020-10-01 12:26:51 +00:00
tx . Signers = [ ] transaction . Signer { { Account : util . Uint160 { } , Scopes : transaction . None } }
2020-06-10 11:45:55 +00:00
}
2020-07-14 14:32:59 +00:00
tx . Script = script
2022-04-07 15:13:08 +00:00
return tx , verbose , nil
2020-12-14 12:23:39 +00:00
}
// invokeContractVerify implements the `invokecontractverify` RPC call.
2023-04-03 10:34:24 +00:00
func ( s * Server ) invokeContractVerify ( reqParams params . Params ) ( any , * neorpc . Error ) {
2022-04-07 15:13:08 +00:00
scriptHash , tx , invocationScript , respErr := s . getInvokeContractVerifyParams ( reqParams )
if respErr != nil {
return nil , respErr
}
return s . runScriptInVM ( trigger . Verification , invocationScript , scriptHash , tx , nil , false )
}
// invokeContractVerifyHistoric implements the `invokecontractverifyhistoric` RPC call.
2023-04-03 10:34:24 +00:00
func ( s * Server ) invokeContractVerifyHistoric ( reqParams params . Params ) ( any , * neorpc . Error ) {
2022-10-06 10:24:57 +00:00
nextH , respErr := s . getHistoricParams ( reqParams )
2022-04-07 15:13:08 +00:00
if respErr != nil {
return nil , respErr
}
if len ( reqParams ) < 2 {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2022-04-07 15:13:08 +00:00
}
scriptHash , tx , invocationScript , respErr := s . getInvokeContractVerifyParams ( reqParams [ 1 : ] )
if respErr != nil {
return nil , respErr
}
2022-10-06 10:24:57 +00:00
return s . runScriptInVM ( trigger . Verification , invocationScript , scriptHash , tx , & nextH , false )
2022-04-07 15:13:08 +00:00
}
2022-07-22 16:09:29 +00:00
func ( s * Server ) getInvokeContractVerifyParams ( reqParams params . Params ) ( util . Uint160 , * transaction . Transaction , [ ] byte , * neorpc . Error ) {
2020-12-14 12:23:39 +00:00
scriptHash , responseErr := s . contractScriptHashFromParam ( reqParams . Value ( 0 ) )
if responseErr != nil {
2022-04-07 15:13:08 +00:00
return util . Uint160 { } , nil , nil , responseErr
2020-12-14 12:23:39 +00:00
}
2021-03-10 14:43:52 +00:00
bw := io . NewBufBinWriter ( )
if len ( reqParams ) > 1 {
args , err := reqParams [ 1 ] . GetArray ( ) // second `invokecontractverify` parameter is an array of arguments for `verify` method
if err != nil {
2022-07-22 16:09:29 +00:00
return util . Uint160 { } , nil , nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , err . Error ( ) )
2021-03-10 14:43:52 +00:00
}
if len ( args ) > 0 {
2022-07-07 14:41:01 +00:00
err := params . ExpandArrayIntoScript ( bw . BinWriter , args )
2021-03-10 14:43:52 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return util . Uint160 { } , nil , nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "can't create witness invocation script: %s" , err ) )
2021-03-10 14:43:52 +00:00
}
}
}
invocationScript := bw . Bytes ( )
tx := & transaction . Transaction { Script : [ ] byte { byte ( opcode . RET ) } } // need something in script
2020-12-14 12:23:39 +00:00
if len ( reqParams ) > 2 {
signers , witnesses , err := reqParams [ 2 ] . GetSignersWithWitnesses ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return util . Uint160 { } , nil , nil , neorpc . ErrInvalidParams
2020-12-14 12:23:39 +00:00
}
2021-03-10 14:43:52 +00:00
tx . Signers = signers
tx . Scripts = witnesses
} else { // fill the only known signer - the contract with `verify` method
tx . Signers = [ ] transaction . Signer { { Account : scriptHash } }
tx . Scripts = [ ] transaction . Witness { { InvocationScript : invocationScript , VerificationScript : [ ] byte { } } }
2020-12-14 12:23:39 +00:00
}
2022-04-07 15:13:08 +00:00
return scriptHash , tx , invocationScript , nil
}
2022-10-07 13:06:12 +00:00
// getHistoricParams checks that historic calls are supported and returns index of
// a fake next block to perform the historic call. It also checks that
2022-04-07 15:13:08 +00:00
// specified stateroot is stored at the specified height for further request
// handling consistency.
2022-10-06 10:24:57 +00:00
func ( s * Server ) getHistoricParams ( reqParams params . Params ) ( uint32 , * neorpc . Error ) {
2022-12-06 13:34:38 +00:00
if s . chain . GetConfig ( ) . Ledger . KeepOnlyLatestState {
2023-08-14 16:43:19 +00:00
return 0 , neorpc . WrapErrorWithData ( neorpc . ErrUnsupportedState , fmt . Sprintf ( "only latest state is supported: %s" , errKeepOnlyLatestState ) )
2022-04-07 15:13:08 +00:00
}
if len ( reqParams ) < 1 {
2022-10-06 10:24:57 +00:00
return 0 , neorpc . ErrInvalidParams
2022-04-07 15:13:08 +00:00
}
height , respErr := s . blockHeightFromParam ( reqParams . Value ( 0 ) )
if respErr != nil {
hash , err := reqParams . Value ( 0 ) . GetUint256 ( )
if err != nil {
2022-10-06 10:24:57 +00:00
return 0 , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "invalid block hash or index or stateroot hash: %s" , err ) )
2022-04-07 15:13:08 +00:00
}
b , err := s . chain . GetBlock ( hash )
if err != nil {
stateH , err := s . chain . GetStateModule ( ) . GetLatestStateHeight ( hash )
if err != nil {
2022-10-06 10:24:57 +00:00
return 0 , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "unknown block or stateroot: %s" , err ) )
2022-04-07 15:13:08 +00:00
}
2022-11-18 20:19:50 +00:00
height = stateH
2022-04-07 15:13:08 +00:00
} else {
2022-11-18 20:19:50 +00:00
height = b . Index
2022-04-07 15:13:08 +00:00
}
}
2022-11-18 20:19:50 +00:00
return height + 1 , nil
2021-11-17 20:04:50 +00:00
}
2020-11-19 15:01:42 +00:00
2022-10-06 10:24:57 +00:00
func ( s * Server ) prepareInvocationContext ( t trigger . Type , script [ ] byte , contractScriptHash util . Uint160 , tx * transaction . Transaction , nextH * uint32 , verbose bool ) ( * interop . Context , * neorpc . Error ) {
2022-04-07 15:13:08 +00:00
var (
err error
ic * interop . Context
)
2022-10-06 10:24:57 +00:00
if nextH == nil {
ic , err = s . chain . GetTestVM ( t , tx , nil )
2022-04-07 15:13:08 +00:00
if err != nil {
2022-10-06 10:24:57 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to create test VM: %s" , err ) )
2022-04-07 15:13:08 +00:00
}
} else {
2022-10-06 10:24:57 +00:00
ic , err = s . chain . GetTestHistoricVM ( t , tx , * nextH )
2022-04-07 15:13:08 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to create historic VM: %s" , err ) )
2022-04-07 15:13:08 +00:00
}
2021-11-17 20:04:50 +00:00
}
2021-11-20 18:55:55 +00:00
if verbose {
2022-01-12 22:20:08 +00:00
ic . VM . EnableInvocationTree ( )
2021-11-20 18:55:55 +00:00
}
2022-01-12 22:20:08 +00:00
ic . VM . GasLimit = int64 ( s . config . MaxGasInvoke )
2021-03-10 14:43:52 +00:00
if t == trigger . Verification {
// We need this special case because witnesses verification is not the simple System.Contract.Call,
// and we need to define exactly the amount of gas consumed for a contract witness verification.
2024-08-23 19:09:20 +00:00
ic . VM . GasLimit = min ( ic . VM . GasLimit , s . chain . GetMaxVerificationGAS ( ) )
2021-03-10 14:43:52 +00:00
2022-04-07 15:13:08 +00:00
err = s . chain . InitVerificationContext ( ic , contractScriptHash , & transaction . Witness { InvocationScript : script , VerificationScript : [ ] byte { } } )
2021-03-10 14:43:52 +00:00
if err != nil {
2023-08-14 16:43:19 +00:00
switch {
case errors . Is ( err , core . ErrUnknownVerificationContract ) :
return nil , neorpc . WrapErrorWithData ( neorpc . ErrUnknownContract , err . Error ( ) )
case errors . Is ( err , core . ErrInvalidVerificationContract ) :
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidVerificationFunction , err . Error ( ) )
default :
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "can't prepare verification VM: %s" , err ) )
}
2021-03-10 14:43:52 +00:00
}
} else {
2022-01-12 22:20:08 +00:00
ic . VM . LoadScriptWithFlags ( script , callflag . All )
2021-03-10 14:43:52 +00:00
}
rpc: add configuration extension for MPT-backed iterator sessions
Add ability to switch between current blockchain storage and MPT-backed
storage for iterator traversing process. It may be useful because
iterator implementation traverses underlying backed storage (BoltDB,
LevelDB) inside DB's Seek which is blocking operation for BoltDB:
```
Opening a read transaction and a write transaction in the same goroutine
can cause the writer to deadlock because the database periodically needs
to re-mmap itself as it grows and it cannot do that while a read transaction
is open.
If a long running read transaction (for example, a snapshot transaction)
is needed, you might want to set DB.InitialMmapSize to a large enough
value to avoid potential blocking of write transaction.
```
So during bbolt re-mmaping, standard blockchain DB operations (i.e. persist)
can be blocked until iterator resourses release. The described behaviour
is tested and confirmed on four-nodes privnet with BoltDB and
`SessionExpirationTime` set to be 180 seconds. After new iterator session
is added to the server, the subsequent persist took ~5m21s, see the log
record `2022-06-17T18:58:21.563+0300`:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go node -p
2022-06-17T18:52:21.535+0300 INFO initial gas supply is not set or wrong, setting default value {"InitialGASSupply": "52000000"}
2022-06-17T18:52:21.535+0300 INFO MaxBlockSize is not set or wrong, setting default value {"MaxBlockSize": 262144}
2022-06-17T18:52:21.535+0300 INFO MaxBlockSystemFee is not set or wrong, setting default value {"MaxBlockSystemFee": 900000000000}
2022-06-17T18:52:21.535+0300 INFO MaxTransactionsPerBlock is not set or wrong, using default value {"MaxTransactionsPerBlock": 512}
2022-06-17T18:52:21.535+0300 INFO MaxValidUntilBlockIncrement is not set or wrong, using default value {"MaxValidUntilBlockIncrement": 5760}
2022-06-17T18:52:21.535+0300 INFO Hardforks are not set, using default value
2022-06-17T18:52:21.543+0300 INFO no storage version found! creating genesis block
2022-06-17T18:52:21.546+0300 INFO ExtensiblePoolSize is not set or wrong, using default value {"ExtensiblePoolSize": 20}
2022-06-17T18:52:21.546+0300 INFO service is running {"service": "Prometheus", "endpoint": ":2112"}
2022-06-17T18:52:21.547+0300 INFO starting rpc-server {"endpoint": ":20331"}
2022-06-17T18:52:21.547+0300 INFO rpc-server iterator sessions are enabled
2022-06-17T18:52:21.547+0300 INFO service hasn't started since it's disabled {"service": "Pprof"}
2022-06-17T18:52:21.547+0300 INFO node started {"blockHeight": 0, "headerHeight": 0}
_ ____________ __________
/ | / / ____/ __ \ / ____/ __ \
/ |/ / __/ / / / /_____/ / __/ / / /
/ /| / /___/ /_/ /_____/ /_/ / /_/ /
/_/ |_/_____/\____/ \____/\____/
/NEO-GO:0.99.1-pre-53-g7ccb646e/
2022-06-17T18:52:21.548+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 1}
2022-06-17T18:52:21.550+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 1475228436}
2022-06-17T18:52:22.575+0300 INFO persisted to disk {"blocks": 65, "keys": 1410, "headerHeight": 65, "blockHeight": 65, "took": "28.193409ms"}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 2}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 3}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 4}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 5}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 6}
2022-06-17T18:52:24.549+0300 INFO started protocol {"addr": "127.0.0.1:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 3444438498}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 7}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 8}
2022-06-17T18:52:24.550+0300 INFO node reached synchronized state, starting services
2022-06-17T18:52:24.550+0300 INFO started protocol {"addr": "127.0.0.1:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 2435677826}
2022-06-17T18:52:24.550+0300 INFO starting state validation service
2022-06-17T18:52:24.550+0300 INFO RPC server already started
2022-06-17T18:52:24.550+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:52:24.550+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 10}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 9}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 7}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 6}
2022-06-17T18:52:24.550+0300 INFO started protocol {"addr": "127.0.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 970555896}
2022-06-17T18:52:24.551+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 7}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 6}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 5}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 4}
2022-06-17T18:52:29.564+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 66, "blockHeight": 66, "took": "12.51808ms"}
2022-06-17T18:52:44.558+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 67, "blockHeight": 67, "took": "1.563137ms"}
2022-06-17T18:55:21.549+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "ping/pong timeout", "peerCount": 3}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "ping/pong timeout", "peerCount": 2}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "ping/pong timeout", "peerCount": 1}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "ping/pong timeout", "peerCount": 0}
2022-06-17T18:55:21.553+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 1}
2022-06-17T18:55:21.554+0300 INFO started protocol {"addr": "127.0.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 970555896}
2022-06-17T18:55:24.554+0300 INFO new peer connected {"addr": "172.200.0.4:20333", "peerCount": 2}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "172.200.0.3:20334", "peerCount": 3}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "10.78.13.84:59876", "peerCount": 4}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 5}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "172.200.0.254:20332", "peerCount": 6}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 7}
2022-06-17T18:55:24.556+0300 INFO started protocol {"addr": "172.200.0.4:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 76, "id": 3444438498}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "172.200.0.1:20335", "peerCount": 8}
2022-06-17T18:55:24.558+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 1475228436}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 9}
2022-06-17T18:55:24.558+0300 INFO started protocol {"addr": "172.200.0.3:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 2435677826}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 10}
2022-06-17T18:55:24.559+0300 WARN peer disconnected {"addr": "172.200.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 10}
2022-06-17T18:55:24.560+0300 INFO new peer connected {"addr": "172.200.0.2:20336", "peerCount": 11}
2022-06-17T18:55:24.560+0300 WARN peer disconnected {"addr": "172.200.0.254:20332", "error": "identical node id", "peerCount": 10}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 9}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 10}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "10.78.13.84:59876", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "172.200.0.2:20336", "error": "unexpected empty payload: CMDVersion", "peerCount": 7}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 9}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 10}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 11}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 12}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 11}
2022-06-17T18:55:24.562+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 12}
2022-06-17T18:55:24.562+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 13}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 12}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 11}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 10}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.563+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 10}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 9}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 7}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "max peers reached", "peerCount": 6}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 5}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "max peers reached", "peerCount": 4}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 3}
2022-06-17T18:57:21.551+0300 WARN peer disconnected {"addr": "172.200.0.4:20333", "error": "ping/pong timeout", "peerCount": 2}
2022-06-17T18:57:21.552+0300 WARN peer disconnected {"addr": "172.200.0.3:20334", "error": "ping/pong timeout", "peerCount": 1}
2022-06-17T18:57:21.552+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "ping/pong timeout", "peerCount": 0}
2022-06-17T18:57:21.553+0300 INFO new peer connected {"addr": "172.200.0.4:20333", "peerCount": 1}
2022-06-17T18:57:21.554+0300 INFO new peer connected {"addr": "10.78.13.84:20332", "peerCount": 2}
2022-06-17T18:57:21.555+0300 INFO started protocol {"addr": "172.200.0.4:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 3444438498}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 3}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "10.78.13.84:46076", "peerCount": 4}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "172.200.0.1:20335", "peerCount": 5}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "172.200.0.254:20332", "peerCount": 6}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "10.78.13.84:59972", "peerCount": 7}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 8}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "172.200.0.2:20336", "peerCount": 10}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 11}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 12}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "172.200.0.3:20334", "peerCount": 13}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 14}
2022-06-17T18:57:21.557+0300 INFO started protocol {"addr": "127.0.0.1:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 2435677826}
2022-06-17T18:57:21.557+0300 WARN peer disconnected {"addr": "172.200.0.2:20336", "error": "max peers reached", "peerCount": 13}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 14}
2022-06-17T18:57:21.558+0300 INFO started protocol {"addr": "172.200.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 970555896}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "172.200.0.254:20332", "error": "identical node id", "peerCount": 13}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 14}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "max peers reached", "peerCount": 13}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "10.78.13.84:46076", "error": "identical node id", "peerCount": 12}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 13}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 14}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 15}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "10.78.13.84:59972", "error": "identical node id", "peerCount": 14}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 13}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "10.78.13.84:20332", "error": "unexpected empty payload: CMDVersion", "peerCount": 12}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 11}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "172.200.0.3:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 10}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 8}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 7}
2022-06-17T18:57:21.559+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 1475228436}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 6}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 5}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 4}
2022-06-17T18:58:21.561+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 68, "blockHeight": 68, "took": "5m21.993873018s"}
2022-06-17T18:58:21.563+0300 INFO persisted to disk {"blocks": 8, "keys": 111, "headerHeight": 76, "blockHeight": 76, "took": "2.243347ms"}
2022-06-17T18:58:22.567+0300 INFO persisted to disk {"blocks": 10, "keys": 135, "headerHeight": 86, "blockHeight": 86, "took": "5.637669ms"}
2022-06-17T18:58:25.565+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 87, "blockHeight": 87, "took": "1.879912ms"}
2022-06-17T18:58:40.572+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 88, "blockHeight": 88, "took": "1.560317ms"}
2022-06-17T18:58:55.579+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 89, "blockHeight": 89, "took": "1.925225ms"}
2022-06-17T18:59:10.587+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 90, "blockHeight": 90, "took": "3.118073ms"}
2022-06-17T18:59:25.592+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 91, "blockHeight": 91, "took": "1.607248ms"}
2022-06-17T18:59:40.600+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 92, "blockHeight": 92, "took": "931.806µs"}
2022-06-17T18:59:55.610+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 93, "blockHeight": 93, "took": "2.019041ms"}
```
2022-06-20 15:20:57 +00:00
return ic , nil
}
// runScriptInVM runs the given script in a new test VM and returns the invocation
// result. The script is either a simple script in case of `application` trigger,
// witness invocation script in case of `verification` trigger (it pushes `verify`
// arguments on stack before verification). In case of contract verification
// contractScriptHash should be specified.
2022-10-06 10:24:57 +00:00
func ( s * Server ) runScriptInVM ( t trigger . Type , script [ ] byte , contractScriptHash util . Uint160 , tx * transaction . Transaction , nextH * uint32 , verbose bool ) ( * result . Invoke , * neorpc . Error ) {
ic , respErr := s . prepareInvocationContext ( t , script , contractScriptHash , tx , nextH , verbose )
rpc: add configuration extension for MPT-backed iterator sessions
Add ability to switch between current blockchain storage and MPT-backed
storage for iterator traversing process. It may be useful because
iterator implementation traverses underlying backed storage (BoltDB,
LevelDB) inside DB's Seek which is blocking operation for BoltDB:
```
Opening a read transaction and a write transaction in the same goroutine
can cause the writer to deadlock because the database periodically needs
to re-mmap itself as it grows and it cannot do that while a read transaction
is open.
If a long running read transaction (for example, a snapshot transaction)
is needed, you might want to set DB.InitialMmapSize to a large enough
value to avoid potential blocking of write transaction.
```
So during bbolt re-mmaping, standard blockchain DB operations (i.e. persist)
can be blocked until iterator resourses release. The described behaviour
is tested and confirmed on four-nodes privnet with BoltDB and
`SessionExpirationTime` set to be 180 seconds. After new iterator session
is added to the server, the subsequent persist took ~5m21s, see the log
record `2022-06-17T18:58:21.563+0300`:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go node -p
2022-06-17T18:52:21.535+0300 INFO initial gas supply is not set or wrong, setting default value {"InitialGASSupply": "52000000"}
2022-06-17T18:52:21.535+0300 INFO MaxBlockSize is not set or wrong, setting default value {"MaxBlockSize": 262144}
2022-06-17T18:52:21.535+0300 INFO MaxBlockSystemFee is not set or wrong, setting default value {"MaxBlockSystemFee": 900000000000}
2022-06-17T18:52:21.535+0300 INFO MaxTransactionsPerBlock is not set or wrong, using default value {"MaxTransactionsPerBlock": 512}
2022-06-17T18:52:21.535+0300 INFO MaxValidUntilBlockIncrement is not set or wrong, using default value {"MaxValidUntilBlockIncrement": 5760}
2022-06-17T18:52:21.535+0300 INFO Hardforks are not set, using default value
2022-06-17T18:52:21.543+0300 INFO no storage version found! creating genesis block
2022-06-17T18:52:21.546+0300 INFO ExtensiblePoolSize is not set or wrong, using default value {"ExtensiblePoolSize": 20}
2022-06-17T18:52:21.546+0300 INFO service is running {"service": "Prometheus", "endpoint": ":2112"}
2022-06-17T18:52:21.547+0300 INFO starting rpc-server {"endpoint": ":20331"}
2022-06-17T18:52:21.547+0300 INFO rpc-server iterator sessions are enabled
2022-06-17T18:52:21.547+0300 INFO service hasn't started since it's disabled {"service": "Pprof"}
2022-06-17T18:52:21.547+0300 INFO node started {"blockHeight": 0, "headerHeight": 0}
_ ____________ __________
/ | / / ____/ __ \ / ____/ __ \
/ |/ / __/ / / / /_____/ / __/ / / /
/ /| / /___/ /_/ /_____/ /_/ / /_/ /
/_/ |_/_____/\____/ \____/\____/
/NEO-GO:0.99.1-pre-53-g7ccb646e/
2022-06-17T18:52:21.548+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 1}
2022-06-17T18:52:21.550+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 1475228436}
2022-06-17T18:52:22.575+0300 INFO persisted to disk {"blocks": 65, "keys": 1410, "headerHeight": 65, "blockHeight": 65, "took": "28.193409ms"}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 2}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 3}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 4}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 5}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 6}
2022-06-17T18:52:24.549+0300 INFO started protocol {"addr": "127.0.0.1:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 3444438498}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 7}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 8}
2022-06-17T18:52:24.550+0300 INFO node reached synchronized state, starting services
2022-06-17T18:52:24.550+0300 INFO started protocol {"addr": "127.0.0.1:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 2435677826}
2022-06-17T18:52:24.550+0300 INFO starting state validation service
2022-06-17T18:52:24.550+0300 INFO RPC server already started
2022-06-17T18:52:24.550+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:52:24.550+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 10}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 9}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 7}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 6}
2022-06-17T18:52:24.550+0300 INFO started protocol {"addr": "127.0.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 970555896}
2022-06-17T18:52:24.551+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 7}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 6}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 5}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 4}
2022-06-17T18:52:29.564+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 66, "blockHeight": 66, "took": "12.51808ms"}
2022-06-17T18:52:44.558+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 67, "blockHeight": 67, "took": "1.563137ms"}
2022-06-17T18:55:21.549+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "ping/pong timeout", "peerCount": 3}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "ping/pong timeout", "peerCount": 2}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "ping/pong timeout", "peerCount": 1}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "ping/pong timeout", "peerCount": 0}
2022-06-17T18:55:21.553+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 1}
2022-06-17T18:55:21.554+0300 INFO started protocol {"addr": "127.0.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 970555896}
2022-06-17T18:55:24.554+0300 INFO new peer connected {"addr": "172.200.0.4:20333", "peerCount": 2}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "172.200.0.3:20334", "peerCount": 3}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "10.78.13.84:59876", "peerCount": 4}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 5}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "172.200.0.254:20332", "peerCount": 6}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 7}
2022-06-17T18:55:24.556+0300 INFO started protocol {"addr": "172.200.0.4:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 76, "id": 3444438498}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "172.200.0.1:20335", "peerCount": 8}
2022-06-17T18:55:24.558+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 1475228436}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 9}
2022-06-17T18:55:24.558+0300 INFO started protocol {"addr": "172.200.0.3:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 2435677826}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 10}
2022-06-17T18:55:24.559+0300 WARN peer disconnected {"addr": "172.200.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 10}
2022-06-17T18:55:24.560+0300 INFO new peer connected {"addr": "172.200.0.2:20336", "peerCount": 11}
2022-06-17T18:55:24.560+0300 WARN peer disconnected {"addr": "172.200.0.254:20332", "error": "identical node id", "peerCount": 10}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 9}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 10}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "10.78.13.84:59876", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "172.200.0.2:20336", "error": "unexpected empty payload: CMDVersion", "peerCount": 7}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 9}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 10}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 11}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 12}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 11}
2022-06-17T18:55:24.562+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 12}
2022-06-17T18:55:24.562+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 13}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 12}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 11}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 10}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.563+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 10}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 9}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 7}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "max peers reached", "peerCount": 6}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 5}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "max peers reached", "peerCount": 4}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 3}
2022-06-17T18:57:21.551+0300 WARN peer disconnected {"addr": "172.200.0.4:20333", "error": "ping/pong timeout", "peerCount": 2}
2022-06-17T18:57:21.552+0300 WARN peer disconnected {"addr": "172.200.0.3:20334", "error": "ping/pong timeout", "peerCount": 1}
2022-06-17T18:57:21.552+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "ping/pong timeout", "peerCount": 0}
2022-06-17T18:57:21.553+0300 INFO new peer connected {"addr": "172.200.0.4:20333", "peerCount": 1}
2022-06-17T18:57:21.554+0300 INFO new peer connected {"addr": "10.78.13.84:20332", "peerCount": 2}
2022-06-17T18:57:21.555+0300 INFO started protocol {"addr": "172.200.0.4:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 3444438498}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 3}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "10.78.13.84:46076", "peerCount": 4}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "172.200.0.1:20335", "peerCount": 5}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "172.200.0.254:20332", "peerCount": 6}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "10.78.13.84:59972", "peerCount": 7}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 8}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "172.200.0.2:20336", "peerCount": 10}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 11}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 12}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "172.200.0.3:20334", "peerCount": 13}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 14}
2022-06-17T18:57:21.557+0300 INFO started protocol {"addr": "127.0.0.1:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 2435677826}
2022-06-17T18:57:21.557+0300 WARN peer disconnected {"addr": "172.200.0.2:20336", "error": "max peers reached", "peerCount": 13}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 14}
2022-06-17T18:57:21.558+0300 INFO started protocol {"addr": "172.200.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 970555896}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "172.200.0.254:20332", "error": "identical node id", "peerCount": 13}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 14}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "max peers reached", "peerCount": 13}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "10.78.13.84:46076", "error": "identical node id", "peerCount": 12}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 13}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 14}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 15}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "10.78.13.84:59972", "error": "identical node id", "peerCount": 14}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 13}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "10.78.13.84:20332", "error": "unexpected empty payload: CMDVersion", "peerCount": 12}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 11}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "172.200.0.3:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 10}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 8}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 7}
2022-06-17T18:57:21.559+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 1475228436}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 6}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 5}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 4}
2022-06-17T18:58:21.561+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 68, "blockHeight": 68, "took": "5m21.993873018s"}
2022-06-17T18:58:21.563+0300 INFO persisted to disk {"blocks": 8, "keys": 111, "headerHeight": 76, "blockHeight": 76, "took": "2.243347ms"}
2022-06-17T18:58:22.567+0300 INFO persisted to disk {"blocks": 10, "keys": 135, "headerHeight": 86, "blockHeight": 86, "took": "5.637669ms"}
2022-06-17T18:58:25.565+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 87, "blockHeight": 87, "took": "1.879912ms"}
2022-06-17T18:58:40.572+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 88, "blockHeight": 88, "took": "1.560317ms"}
2022-06-17T18:58:55.579+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 89, "blockHeight": 89, "took": "1.925225ms"}
2022-06-17T18:59:10.587+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 90, "blockHeight": 90, "took": "3.118073ms"}
2022-06-17T18:59:25.592+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 91, "blockHeight": 91, "took": "1.607248ms"}
2022-06-17T18:59:40.600+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 92, "blockHeight": 92, "took": "931.806µs"}
2022-06-17T18:59:55.610+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 93, "blockHeight": 93, "took": "2.019041ms"}
```
2022-06-20 15:20:57 +00:00
if respErr != nil {
return nil , respErr
}
err := ic . VM . Run ( )
2020-10-05 13:33:20 +00:00
var faultException string
if err != nil {
faultException = err . Error ( )
}
2022-07-08 20:25:22 +00:00
items := ic . VM . Estack ( ) . ToArray ( )
sess := s . postProcessExecStack ( items )
var id uuid . UUID
if sess != nil {
2022-10-06 10:24:57 +00:00
// nextH == nil only when we're not using MPT-backed storage, therefore
2022-07-08 20:25:22 +00:00
// the second attempt won't stop here.
2022-10-06 10:24:57 +00:00
if s . config . SessionBackedByMPT && nextH == nil {
2022-07-08 20:25:22 +00:00
ic . Finalize ( )
// Rerun with MPT-backed storage.
2022-10-06 10:24:57 +00:00
return s . runScriptInVM ( t , script , contractScriptHash , tx , & ic . Block . Index , verbose )
2022-07-08 20:25:22 +00:00
}
id = uuid . New ( )
sessionID := id . String ( )
sess . finalize = ic . Finalize
sess . timer = time . AfterFunc ( time . Second * time . Duration ( s . config . SessionExpirationTime ) , func ( ) {
2022-07-07 19:03:11 +00:00
s . sessionsLock . Lock ( )
2022-07-08 20:25:22 +00:00
defer s . sessionsLock . Unlock ( )
if len ( s . sessions ) == 0 {
return
}
2022-07-07 19:03:11 +00:00
sess , ok := s . sessions [ sessionID ]
if ! ok {
2022-07-08 20:25:22 +00:00
return
rpc: add configuration extension for MPT-backed iterator sessions
Add ability to switch between current blockchain storage and MPT-backed
storage for iterator traversing process. It may be useful because
iterator implementation traverses underlying backed storage (BoltDB,
LevelDB) inside DB's Seek which is blocking operation for BoltDB:
```
Opening a read transaction and a write transaction in the same goroutine
can cause the writer to deadlock because the database periodically needs
to re-mmap itself as it grows and it cannot do that while a read transaction
is open.
If a long running read transaction (for example, a snapshot transaction)
is needed, you might want to set DB.InitialMmapSize to a large enough
value to avoid potential blocking of write transaction.
```
So during bbolt re-mmaping, standard blockchain DB operations (i.e. persist)
can be blocked until iterator resourses release. The described behaviour
is tested and confirmed on four-nodes privnet with BoltDB and
`SessionExpirationTime` set to be 180 seconds. After new iterator session
is added to the server, the subsequent persist took ~5m21s, see the log
record `2022-06-17T18:58:21.563+0300`:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go node -p
2022-06-17T18:52:21.535+0300 INFO initial gas supply is not set or wrong, setting default value {"InitialGASSupply": "52000000"}
2022-06-17T18:52:21.535+0300 INFO MaxBlockSize is not set or wrong, setting default value {"MaxBlockSize": 262144}
2022-06-17T18:52:21.535+0300 INFO MaxBlockSystemFee is not set or wrong, setting default value {"MaxBlockSystemFee": 900000000000}
2022-06-17T18:52:21.535+0300 INFO MaxTransactionsPerBlock is not set or wrong, using default value {"MaxTransactionsPerBlock": 512}
2022-06-17T18:52:21.535+0300 INFO MaxValidUntilBlockIncrement is not set or wrong, using default value {"MaxValidUntilBlockIncrement": 5760}
2022-06-17T18:52:21.535+0300 INFO Hardforks are not set, using default value
2022-06-17T18:52:21.543+0300 INFO no storage version found! creating genesis block
2022-06-17T18:52:21.546+0300 INFO ExtensiblePoolSize is not set or wrong, using default value {"ExtensiblePoolSize": 20}
2022-06-17T18:52:21.546+0300 INFO service is running {"service": "Prometheus", "endpoint": ":2112"}
2022-06-17T18:52:21.547+0300 INFO starting rpc-server {"endpoint": ":20331"}
2022-06-17T18:52:21.547+0300 INFO rpc-server iterator sessions are enabled
2022-06-17T18:52:21.547+0300 INFO service hasn't started since it's disabled {"service": "Pprof"}
2022-06-17T18:52:21.547+0300 INFO node started {"blockHeight": 0, "headerHeight": 0}
_ ____________ __________
/ | / / ____/ __ \ / ____/ __ \
/ |/ / __/ / / / /_____/ / __/ / / /
/ /| / /___/ /_/ /_____/ /_/ / /_/ /
/_/ |_/_____/\____/ \____/\____/
/NEO-GO:0.99.1-pre-53-g7ccb646e/
2022-06-17T18:52:21.548+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 1}
2022-06-17T18:52:21.550+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 1475228436}
2022-06-17T18:52:22.575+0300 INFO persisted to disk {"blocks": 65, "keys": 1410, "headerHeight": 65, "blockHeight": 65, "took": "28.193409ms"}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 2}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 3}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 4}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 5}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 6}
2022-06-17T18:52:24.549+0300 INFO started protocol {"addr": "127.0.0.1:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 3444438498}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 7}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 8}
2022-06-17T18:52:24.550+0300 INFO node reached synchronized state, starting services
2022-06-17T18:52:24.550+0300 INFO started protocol {"addr": "127.0.0.1:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 2435677826}
2022-06-17T18:52:24.550+0300 INFO starting state validation service
2022-06-17T18:52:24.550+0300 INFO RPC server already started
2022-06-17T18:52:24.550+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:52:24.550+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 10}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 9}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 7}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 6}
2022-06-17T18:52:24.550+0300 INFO started protocol {"addr": "127.0.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 970555896}
2022-06-17T18:52:24.551+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 7}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 6}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 5}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 4}
2022-06-17T18:52:29.564+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 66, "blockHeight": 66, "took": "12.51808ms"}
2022-06-17T18:52:44.558+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 67, "blockHeight": 67, "took": "1.563137ms"}
2022-06-17T18:55:21.549+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "ping/pong timeout", "peerCount": 3}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "ping/pong timeout", "peerCount": 2}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "ping/pong timeout", "peerCount": 1}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "ping/pong timeout", "peerCount": 0}
2022-06-17T18:55:21.553+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 1}
2022-06-17T18:55:21.554+0300 INFO started protocol {"addr": "127.0.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 970555896}
2022-06-17T18:55:24.554+0300 INFO new peer connected {"addr": "172.200.0.4:20333", "peerCount": 2}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "172.200.0.3:20334", "peerCount": 3}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "10.78.13.84:59876", "peerCount": 4}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 5}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "172.200.0.254:20332", "peerCount": 6}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 7}
2022-06-17T18:55:24.556+0300 INFO started protocol {"addr": "172.200.0.4:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 76, "id": 3444438498}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "172.200.0.1:20335", "peerCount": 8}
2022-06-17T18:55:24.558+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 1475228436}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 9}
2022-06-17T18:55:24.558+0300 INFO started protocol {"addr": "172.200.0.3:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 2435677826}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 10}
2022-06-17T18:55:24.559+0300 WARN peer disconnected {"addr": "172.200.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 10}
2022-06-17T18:55:24.560+0300 INFO new peer connected {"addr": "172.200.0.2:20336", "peerCount": 11}
2022-06-17T18:55:24.560+0300 WARN peer disconnected {"addr": "172.200.0.254:20332", "error": "identical node id", "peerCount": 10}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 9}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 10}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "10.78.13.84:59876", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "172.200.0.2:20336", "error": "unexpected empty payload: CMDVersion", "peerCount": 7}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 9}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 10}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 11}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 12}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 11}
2022-06-17T18:55:24.562+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 12}
2022-06-17T18:55:24.562+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 13}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 12}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 11}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 10}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.563+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 10}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 9}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 7}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "max peers reached", "peerCount": 6}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 5}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "max peers reached", "peerCount": 4}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 3}
2022-06-17T18:57:21.551+0300 WARN peer disconnected {"addr": "172.200.0.4:20333", "error": "ping/pong timeout", "peerCount": 2}
2022-06-17T18:57:21.552+0300 WARN peer disconnected {"addr": "172.200.0.3:20334", "error": "ping/pong timeout", "peerCount": 1}
2022-06-17T18:57:21.552+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "ping/pong timeout", "peerCount": 0}
2022-06-17T18:57:21.553+0300 INFO new peer connected {"addr": "172.200.0.4:20333", "peerCount": 1}
2022-06-17T18:57:21.554+0300 INFO new peer connected {"addr": "10.78.13.84:20332", "peerCount": 2}
2022-06-17T18:57:21.555+0300 INFO started protocol {"addr": "172.200.0.4:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 3444438498}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 3}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "10.78.13.84:46076", "peerCount": 4}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "172.200.0.1:20335", "peerCount": 5}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "172.200.0.254:20332", "peerCount": 6}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "10.78.13.84:59972", "peerCount": 7}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 8}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "172.200.0.2:20336", "peerCount": 10}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 11}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 12}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "172.200.0.3:20334", "peerCount": 13}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 14}
2022-06-17T18:57:21.557+0300 INFO started protocol {"addr": "127.0.0.1:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 2435677826}
2022-06-17T18:57:21.557+0300 WARN peer disconnected {"addr": "172.200.0.2:20336", "error": "max peers reached", "peerCount": 13}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 14}
2022-06-17T18:57:21.558+0300 INFO started protocol {"addr": "172.200.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 970555896}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "172.200.0.254:20332", "error": "identical node id", "peerCount": 13}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 14}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "max peers reached", "peerCount": 13}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "10.78.13.84:46076", "error": "identical node id", "peerCount": 12}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 13}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 14}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 15}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "10.78.13.84:59972", "error": "identical node id", "peerCount": 14}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 13}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "10.78.13.84:20332", "error": "unexpected empty payload: CMDVersion", "peerCount": 12}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 11}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "172.200.0.3:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 10}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 8}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 7}
2022-06-17T18:57:21.559+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 1475228436}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 6}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 5}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 4}
2022-06-17T18:58:21.561+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 68, "blockHeight": 68, "took": "5m21.993873018s"}
2022-06-17T18:58:21.563+0300 INFO persisted to disk {"blocks": 8, "keys": 111, "headerHeight": 76, "blockHeight": 76, "took": "2.243347ms"}
2022-06-17T18:58:22.567+0300 INFO persisted to disk {"blocks": 10, "keys": 135, "headerHeight": 86, "blockHeight": 86, "took": "5.637669ms"}
2022-06-17T18:58:25.565+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 87, "blockHeight": 87, "took": "1.879912ms"}
2022-06-17T18:58:40.572+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 88, "blockHeight": 88, "took": "1.560317ms"}
2022-06-17T18:58:55.579+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 89, "blockHeight": 89, "took": "1.925225ms"}
2022-06-17T18:59:10.587+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 90, "blockHeight": 90, "took": "3.118073ms"}
2022-06-17T18:59:25.592+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 91, "blockHeight": 91, "took": "1.607248ms"}
2022-06-17T18:59:40.600+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 92, "blockHeight": 92, "took": "931.806µs"}
2022-06-17T18:59:55.610+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 93, "blockHeight": 93, "took": "2.019041ms"}
```
2022-06-20 15:20:57 +00:00
}
2022-07-08 20:25:22 +00:00
sess . iteratorsLock . Lock ( )
sess . finalize ( )
delete ( s . sessions , sessionID )
sess . iteratorsLock . Unlock ( )
} )
s . sessionsLock . Lock ( )
if len ( s . sessions ) >= s . config . SessionPoolSize {
ic . Finalize ( )
s . sessionsLock . Unlock ( )
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( "max session capacity reached" )
2022-07-08 20:25:22 +00:00
}
s . sessions [ sessionID ] = sess
s . sessionsLock . Unlock ( )
} else {
ic . Finalize ( )
}
var diag * result . InvokeDiag
tree := ic . VM . GetInvocationTree ( )
if tree != nil {
diag = & result . InvokeDiag {
Invocations : tree . Calls ,
Changes : storage . BatchToOperations ( ic . DAO . GetBatch ( ) ) ,
}
}
notifications := ic . Notifications
if notifications == nil {
notifications = make ( [ ] state . NotificationEvent , 0 )
}
res := & result . Invoke {
State : ic . VM . State ( ) . String ( ) ,
GasConsumed : ic . VM . GasConsumed ( ) ,
Script : script ,
Stack : items ,
FaultException : faultException ,
Notifications : notifications ,
Diagnostics : diag ,
Session : id ,
}
return res , nil
}
// postProcessExecStack changes iterator interop items according to the server configuration.
// It does modifications in-place, but it returns a session if any iterator was registered.
func ( s * Server ) postProcessExecStack ( stack [ ] stackitem . Item ) * session {
var sess session
for i , v := range stack {
var id uuid . UUID
stack [ i ] , id = s . registerOrDumpIterator ( v )
if id != ( uuid . UUID { } ) {
2022-07-07 19:03:11 +00:00
sess . iteratorIdentifiers = append ( sess . iteratorIdentifiers , & iteratorIdentifier {
2022-07-08 20:25:22 +00:00
ID : id . String ( ) ,
Item : v ,
2022-07-07 19:03:11 +00:00
} )
rpc: add configuration extension for MPT-backed iterator sessions
Add ability to switch between current blockchain storage and MPT-backed
storage for iterator traversing process. It may be useful because
iterator implementation traverses underlying backed storage (BoltDB,
LevelDB) inside DB's Seek which is blocking operation for BoltDB:
```
Opening a read transaction and a write transaction in the same goroutine
can cause the writer to deadlock because the database periodically needs
to re-mmap itself as it grows and it cannot do that while a read transaction
is open.
If a long running read transaction (for example, a snapshot transaction)
is needed, you might want to set DB.InitialMmapSize to a large enough
value to avoid potential blocking of write transaction.
```
So during bbolt re-mmaping, standard blockchain DB operations (i.e. persist)
can be blocked until iterator resourses release. The described behaviour
is tested and confirmed on four-nodes privnet with BoltDB and
`SessionExpirationTime` set to be 180 seconds. After new iterator session
is added to the server, the subsequent persist took ~5m21s, see the log
record `2022-06-17T18:58:21.563+0300`:
```
anna@kiwi:~/Documents/GitProjects/nspcc-dev/neo-go$ ./bin/neo-go node -p
2022-06-17T18:52:21.535+0300 INFO initial gas supply is not set or wrong, setting default value {"InitialGASSupply": "52000000"}
2022-06-17T18:52:21.535+0300 INFO MaxBlockSize is not set or wrong, setting default value {"MaxBlockSize": 262144}
2022-06-17T18:52:21.535+0300 INFO MaxBlockSystemFee is not set or wrong, setting default value {"MaxBlockSystemFee": 900000000000}
2022-06-17T18:52:21.535+0300 INFO MaxTransactionsPerBlock is not set or wrong, using default value {"MaxTransactionsPerBlock": 512}
2022-06-17T18:52:21.535+0300 INFO MaxValidUntilBlockIncrement is not set or wrong, using default value {"MaxValidUntilBlockIncrement": 5760}
2022-06-17T18:52:21.535+0300 INFO Hardforks are not set, using default value
2022-06-17T18:52:21.543+0300 INFO no storage version found! creating genesis block
2022-06-17T18:52:21.546+0300 INFO ExtensiblePoolSize is not set or wrong, using default value {"ExtensiblePoolSize": 20}
2022-06-17T18:52:21.546+0300 INFO service is running {"service": "Prometheus", "endpoint": ":2112"}
2022-06-17T18:52:21.547+0300 INFO starting rpc-server {"endpoint": ":20331"}
2022-06-17T18:52:21.547+0300 INFO rpc-server iterator sessions are enabled
2022-06-17T18:52:21.547+0300 INFO service hasn't started since it's disabled {"service": "Pprof"}
2022-06-17T18:52:21.547+0300 INFO node started {"blockHeight": 0, "headerHeight": 0}
_ ____________ __________
/ | / / ____/ __ \ / ____/ __ \
/ |/ / __/ / / / /_____/ / __/ / / /
/ /| / /___/ /_/ /_____/ /_/ / /_/ /
/_/ |_/_____/\____/ \____/\____/
/NEO-GO:0.99.1-pre-53-g7ccb646e/
2022-06-17T18:52:21.548+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 1}
2022-06-17T18:52:21.550+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 1475228436}
2022-06-17T18:52:22.575+0300 INFO persisted to disk {"blocks": 65, "keys": 1410, "headerHeight": 65, "blockHeight": 65, "took": "28.193409ms"}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 2}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 3}
2022-06-17T18:52:24.548+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 4}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 5}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 6}
2022-06-17T18:52:24.549+0300 INFO started protocol {"addr": "127.0.0.1:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 3444438498}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 7}
2022-06-17T18:52:24.549+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 8}
2022-06-17T18:52:24.550+0300 INFO node reached synchronized state, starting services
2022-06-17T18:52:24.550+0300 INFO started protocol {"addr": "127.0.0.1:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 2435677826}
2022-06-17T18:52:24.550+0300 INFO starting state validation service
2022-06-17T18:52:24.550+0300 INFO RPC server already started
2022-06-17T18:52:24.550+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:52:24.550+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 10}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 9}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 7}
2022-06-17T18:52:24.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 6}
2022-06-17T18:52:24.550+0300 INFO started protocol {"addr": "127.0.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 65, "id": 970555896}
2022-06-17T18:52:24.551+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 7}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 6}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 5}
2022-06-17T18:52:24.551+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 4}
2022-06-17T18:52:29.564+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 66, "blockHeight": 66, "took": "12.51808ms"}
2022-06-17T18:52:44.558+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 67, "blockHeight": 67, "took": "1.563137ms"}
2022-06-17T18:55:21.549+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "ping/pong timeout", "peerCount": 3}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "ping/pong timeout", "peerCount": 2}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "ping/pong timeout", "peerCount": 1}
2022-06-17T18:55:21.550+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "ping/pong timeout", "peerCount": 0}
2022-06-17T18:55:21.553+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 1}
2022-06-17T18:55:21.554+0300 INFO started protocol {"addr": "127.0.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 970555896}
2022-06-17T18:55:24.554+0300 INFO new peer connected {"addr": "172.200.0.4:20333", "peerCount": 2}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "172.200.0.3:20334", "peerCount": 3}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "10.78.13.84:59876", "peerCount": 4}
2022-06-17T18:55:24.555+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 5}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "172.200.0.254:20332", "peerCount": 6}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 7}
2022-06-17T18:55:24.556+0300 INFO started protocol {"addr": "172.200.0.4:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 76, "id": 3444438498}
2022-06-17T18:55:24.556+0300 INFO new peer connected {"addr": "172.200.0.1:20335", "peerCount": 8}
2022-06-17T18:55:24.558+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 1475228436}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 9}
2022-06-17T18:55:24.558+0300 INFO started protocol {"addr": "172.200.0.3:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 77, "id": 2435677826}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 10}
2022-06-17T18:55:24.559+0300 WARN peer disconnected {"addr": "172.200.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.559+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 10}
2022-06-17T18:55:24.560+0300 INFO new peer connected {"addr": "172.200.0.2:20336", "peerCount": 11}
2022-06-17T18:55:24.560+0300 WARN peer disconnected {"addr": "172.200.0.254:20332", "error": "identical node id", "peerCount": 10}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 9}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 10}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "10.78.13.84:59876", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "172.200.0.2:20336", "error": "unexpected empty payload: CMDVersion", "peerCount": 7}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 9}
2022-06-17T18:55:24.561+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 8}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 9}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 10}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 11}
2022-06-17T18:55:24.561+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 12}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 11}
2022-06-17T18:55:24.562+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 12}
2022-06-17T18:55:24.562+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 13}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 12}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 11}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 10}
2022-06-17T18:55:24.562+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:55:24.563+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 10}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 9}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 8}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 7}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "max peers reached", "peerCount": 6}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 5}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "max peers reached", "peerCount": 4}
2022-06-17T18:55:24.563+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 3}
2022-06-17T18:57:21.551+0300 WARN peer disconnected {"addr": "172.200.0.4:20333", "error": "ping/pong timeout", "peerCount": 2}
2022-06-17T18:57:21.552+0300 WARN peer disconnected {"addr": "172.200.0.3:20334", "error": "ping/pong timeout", "peerCount": 1}
2022-06-17T18:57:21.552+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "ping/pong timeout", "peerCount": 0}
2022-06-17T18:57:21.553+0300 INFO new peer connected {"addr": "172.200.0.4:20333", "peerCount": 1}
2022-06-17T18:57:21.554+0300 INFO new peer connected {"addr": "10.78.13.84:20332", "peerCount": 2}
2022-06-17T18:57:21.555+0300 INFO started protocol {"addr": "172.200.0.4:20333", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 3444438498}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 3}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "10.78.13.84:46076", "peerCount": 4}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "172.200.0.1:20335", "peerCount": 5}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "172.200.0.254:20332", "peerCount": 6}
2022-06-17T18:57:21.556+0300 INFO new peer connected {"addr": "10.78.13.84:59972", "peerCount": 7}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 8}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 9}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "172.200.0.2:20336", "peerCount": 10}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 11}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 12}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "172.200.0.3:20334", "peerCount": 13}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 14}
2022-06-17T18:57:21.557+0300 INFO started protocol {"addr": "127.0.0.1:20334", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 2435677826}
2022-06-17T18:57:21.557+0300 WARN peer disconnected {"addr": "172.200.0.2:20336", "error": "max peers reached", "peerCount": 13}
2022-06-17T18:57:21.557+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 14}
2022-06-17T18:57:21.558+0300 INFO started protocol {"addr": "172.200.0.1:20335", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 970555896}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "172.200.0.254:20332", "error": "identical node id", "peerCount": 13}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20334", "peerCount": 14}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "max peers reached", "peerCount": 13}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "10.78.13.84:46076", "error": "identical node id", "peerCount": 12}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20333", "peerCount": 13}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20335", "peerCount": 14}
2022-06-17T18:57:21.558+0300 INFO new peer connected {"addr": "127.0.0.1:20336", "peerCount": 15}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "10.78.13.84:59972", "error": "identical node id", "peerCount": 14}
2022-06-17T18:57:21.558+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 13}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "10.78.13.84:20332", "error": "unexpected empty payload: CMDVersion", "peerCount": 12}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 11}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "172.200.0.3:20334", "error": "unexpected empty payload: CMDVersion", "peerCount": 10}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "unexpected empty payload: CMDVersion", "peerCount": 9}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20334", "error": "already connected", "peerCount": 8}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "unexpected empty payload: CMDVersion", "peerCount": 7}
2022-06-17T18:57:21.559+0300 INFO started protocol {"addr": "127.0.0.1:20336", "userAgent": "/NEO-GO:0.99.1-pre-53-g7ccb646e/", "startHeight": 82, "id": 1475228436}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20333", "error": "already connected", "peerCount": 6}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20335", "error": "already connected", "peerCount": 5}
2022-06-17T18:57:21.559+0300 WARN peer disconnected {"addr": "127.0.0.1:20336", "error": "already connected", "peerCount": 4}
2022-06-17T18:58:21.561+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 68, "blockHeight": 68, "took": "5m21.993873018s"}
2022-06-17T18:58:21.563+0300 INFO persisted to disk {"blocks": 8, "keys": 111, "headerHeight": 76, "blockHeight": 76, "took": "2.243347ms"}
2022-06-17T18:58:22.567+0300 INFO persisted to disk {"blocks": 10, "keys": 135, "headerHeight": 86, "blockHeight": 86, "took": "5.637669ms"}
2022-06-17T18:58:25.565+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 87, "blockHeight": 87, "took": "1.879912ms"}
2022-06-17T18:58:40.572+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 88, "blockHeight": 88, "took": "1.560317ms"}
2022-06-17T18:58:55.579+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 89, "blockHeight": 89, "took": "1.925225ms"}
2022-06-17T18:59:10.587+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 90, "blockHeight": 90, "took": "3.118073ms"}
2022-06-17T18:59:25.592+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 91, "blockHeight": 91, "took": "1.607248ms"}
2022-06-17T18:59:40.600+0300 INFO persisted to disk {"blocks": 1, "keys": 20, "headerHeight": 92, "blockHeight": 92, "took": "931.806µs"}
2022-06-17T18:59:55.610+0300 INFO persisted to disk {"blocks": 1, "keys": 19, "headerHeight": 93, "blockHeight": 93, "took": "2.019041ms"}
```
2022-06-20 15:20:57 +00:00
}
2022-06-15 18:23:29 +00:00
}
2022-07-08 20:25:22 +00:00
if len ( sess . iteratorIdentifiers ) != 0 {
return & sess
}
return nil
}
// registerOrDumpIterator changes iterator interop stack items into result.Iterator
// interop stack items and returns a uuid for it if sessions are enabled. All the other stack
// items are not changed.
func ( s * Server ) registerOrDumpIterator ( item stackitem . Item ) ( stackitem . Item , uuid . UUID ) {
var iterID uuid . UUID
if ( item . Type ( ) != stackitem . InteropT ) || ! iterator . IsIterator ( item ) {
return item , iterID
}
var resIterator result . Iterator
if s . config . SessionEnabled {
iterID = uuid . New ( )
resIterator . ID = & iterID
} else {
resIterator . Values , resIterator . Truncated = iterator . ValuesTruncated ( item , s . config . MaxIteratorResultItems )
}
return stackitem . NewInterop ( resIterator ) , iterID
2022-06-15 18:23:29 +00:00
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) traverseIterator ( reqParams params . Params ) ( any , * neorpc . Error ) {
2022-06-15 18:23:29 +00:00
if ! s . config . SessionEnabled {
2023-08-14 16:43:19 +00:00
return nil , neorpc . ErrSessionsDisabled
2022-06-15 18:23:29 +00:00
}
sID , err := reqParams . Value ( 0 ) . GetUUID ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "invalid session ID: %s" , err ) )
2022-06-15 18:23:29 +00:00
}
iID , err := reqParams . Value ( 1 ) . GetUUID ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "invalid iterator ID: %s" , err ) )
2022-06-15 18:23:29 +00:00
}
count , err := reqParams . Value ( 2 ) . GetInt ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "invalid iterator items count: %s" , err ) )
2022-06-15 18:23:29 +00:00
}
if err := checkInt32 ( count ) ; err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( "invalid iterator items count: not an int32" )
2022-06-15 18:23:29 +00:00
}
if count > s . config . MaxIteratorResultItems {
2023-08-29 09:33:24 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "iterator items count (%d) is out of range (%d at max)" , count , s . config . MaxIteratorResultItems ) )
2022-06-15 18:23:29 +00:00
}
s . sessionsLock . Lock ( )
session , ok := s . sessions [ sID . String ( ) ]
if ! ok {
s . sessionsLock . Unlock ( )
2023-08-13 20:33:49 +00:00
return nil , neorpc . ErrUnknownSession
2022-06-15 18:23:29 +00:00
}
session . iteratorsLock . Lock ( )
// Perform `till` update only after session.iteratorsLock is taken in order to have more
// precise session lifetime.
session . timer . Reset ( time . Second * time . Duration ( s . config . SessionExpirationTime ) )
s . sessionsLock . Unlock ( )
var (
2022-07-08 20:25:22 +00:00
iIDStr = iID . String ( )
iVals [ ] stackitem . Item
2023-08-13 20:33:49 +00:00
found bool
2022-06-15 18:23:29 +00:00
)
2022-07-07 19:03:11 +00:00
for _ , it := range session . iteratorIdentifiers {
2022-06-15 18:23:29 +00:00
if iIDStr == it . ID {
2022-07-07 19:03:11 +00:00
iVals = iterator . Values ( it . Item , count )
2023-08-13 20:33:49 +00:00
found = true
2022-06-15 18:23:29 +00:00
break
}
}
session . iteratorsLock . Unlock ( )
2023-08-13 20:33:49 +00:00
if ! found {
return nil , neorpc . ErrUnknownIterator
}
2022-06-15 18:23:29 +00:00
result := make ( [ ] json . RawMessage , len ( iVals ) )
for j := range iVals {
result [ j ] , err = stackitem . ToJSONWithTypes ( iVals [ j ] )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( fmt . Sprintf ( "failed to marshal iterator value: %s" , err ) )
2022-06-15 18:23:29 +00:00
}
}
return result , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) terminateSession ( reqParams params . Params ) ( any , * neorpc . Error ) {
2022-06-15 18:23:29 +00:00
if ! s . config . SessionEnabled {
2023-08-14 16:43:19 +00:00
return nil , neorpc . ErrSessionsDisabled
2022-06-15 18:23:29 +00:00
}
sID , err := reqParams . Value ( 0 ) . GetUUID ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "invalid session ID: %s" , err ) )
2022-06-15 18:23:29 +00:00
}
strSID := sID . String ( )
s . sessionsLock . Lock ( )
defer s . sessionsLock . Unlock ( )
session , ok := s . sessions [ strSID ]
2023-08-13 20:33:49 +00:00
if ! ok {
return nil , neorpc . ErrUnknownSession
2022-06-15 18:23:29 +00:00
}
2023-08-13 20:33:49 +00:00
// Iterators access Seek channel under the hood; finalizer closes this channel, thus,
// we need to perform finalisation under iteratorsLock.
session . iteratorsLock . Lock ( )
session . finalize ( )
if ! session . timer . Stop ( ) {
<- session . timer . C
}
delete ( s . sessions , strSID )
session . iteratorsLock . Unlock ( )
2022-06-15 18:23:29 +00:00
return ok , nil
2019-10-29 15:31:39 +00:00
}
2022-12-07 13:51:03 +00:00
// submitBlock broadcasts a raw block over the Neo network.
2023-04-03 10:34:24 +00:00
func ( s * Server ) submitBlock ( reqParams params . Params ) ( any , * neorpc . Error ) {
2021-10-28 11:10:18 +00:00
blockBytes , err := reqParams . Value ( 0 ) . GetBytesBase64 ( )
2020-03-02 17:01:32 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "missing parameter or not a base64: %s" , err ) )
2020-03-02 17:01:32 +00:00
}
2021-03-25 18:46:52 +00:00
b := block . New ( s . stateRootEnabled )
2020-03-02 17:01:32 +00:00
r := io . NewBinReaderFromBuf ( blockBytes )
b . DecodeBinary ( r )
if r . Err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "can't decode block: %s" , r . Err ) )
2020-03-02 17:01:32 +00:00
}
2023-08-14 16:43:19 +00:00
return getRelayResult ( s . chain . AddBlock ( b ) , b . Hash ( ) )
2020-03-02 17:01:32 +00:00
}
2022-12-07 13:51:03 +00:00
// submitNotaryRequest broadcasts P2PNotaryRequest over the Neo network.
2023-04-03 10:34:24 +00:00
func ( s * Server ) submitNotaryRequest ( ps params . Params ) ( any , * neorpc . Error ) {
2021-02-05 07:26:23 +00:00
if ! s . chain . P2PSigExtensionsEnabled ( ) {
2023-08-14 16:43:19 +00:00
return nil , neorpc . NewInternalServerError ( "P2PSignatureExtensions are disabled" )
2021-02-05 07:26:23 +00:00
}
2021-10-29 14:06:45 +00:00
bytePayload , err := ps . Value ( 0 ) . GetBytesBase64 ( )
2021-02-05 07:26:23 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "not a base64: %s" , err ) )
2021-02-05 07:26:23 +00:00
}
2021-03-25 19:18:47 +00:00
r , err := payload . NewP2PNotaryRequestFromBytes ( bytePayload )
2021-02-05 07:26:23 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "can't decode notary payload: %s" , err ) )
2021-02-05 07:26:23 +00:00
}
return getRelayResult ( s . coreServer . RelayP2PNotaryRequest ( r ) , r . FallbackTransaction . Hash ( ) )
}
// getRelayResult returns successful relay result or an error.
2023-04-03 10:34:24 +00:00
func getRelayResult ( err error , hash util . Uint256 ) ( any , * neorpc . Error ) {
2021-02-17 11:51:54 +00:00
switch {
case err == nil :
2021-02-05 07:26:23 +00:00
return result . RelayResult {
Hash : hash ,
} , nil
2023-08-14 16:43:19 +00:00
case errors . Is ( err , core . ErrTxExpired ) :
return nil , neorpc . WrapErrorWithData ( neorpc . ErrExpiredTransaction , err . Error ( ) )
case errors . Is ( err , core . ErrAlreadyExists ) || errors . Is ( err , core . ErrInvalidBlockIndex ) :
2022-07-22 16:09:29 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrAlreadyExists , err . Error ( ) )
2023-08-14 16:43:19 +00:00
case errors . Is ( err , core . ErrAlreadyInPool ) :
return nil , neorpc . WrapErrorWithData ( neorpc . ErrAlreadyInPool , err . Error ( ) )
2021-02-17 11:51:54 +00:00
case errors . Is ( err , core . ErrOOM ) :
2023-08-14 16:43:19 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrMempoolCapReached , err . Error ( ) )
2021-02-17 11:51:54 +00:00
case errors . Is ( err , core . ErrPolicy ) :
2023-08-14 16:43:19 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrPolicyFailed , err . Error ( ) )
case errors . Is ( err , core . ErrInvalidScript ) :
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidScript , err . Error ( ) )
case errors . Is ( err , core . ErrTxTooBig ) :
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidSize , err . Error ( ) )
case errors . Is ( err , core . ErrTxSmallNetworkFee ) :
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInsufficientNetworkFee , err . Error ( ) )
case errors . Is ( err , core . ErrInvalidAttribute ) :
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidAttribute , err . Error ( ) )
2024-03-18 17:35:49 +00:00
case errors . Is ( err , core . ErrInsufficientFunds ) , errors . Is ( err , core . ErrMemPoolConflict ) :
2023-08-14 16:43:19 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInsufficientFunds , err . Error ( ) )
case errors . Is ( err , core . ErrInvalidSignature ) :
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidSignature , err . Error ( ) )
2021-02-05 07:26:23 +00:00
default :
2023-08-14 16:43:19 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrVerificationFailed , err . Error ( ) )
2021-02-05 07:26:23 +00:00
}
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) submitOracleResponse ( ps params . Params ) ( any , * neorpc . Error ) {
2023-08-09 12:14:06 +00:00
oraclePtr := s . oracle . Load ( )
if oraclePtr == nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . ErrOracleDisabled
2020-09-28 11:58:04 +00:00
}
2023-08-09 12:14:06 +00:00
oracle := oraclePtr . ( OracleHandler )
2020-09-28 11:58:04 +00:00
var pub * keys . PublicKey
pubBytes , err := ps . Value ( 0 ) . GetBytesBase64 ( )
if err == nil {
pub , err = keys . NewPublicKeyFromBytes ( pubBytes , elliptic . P256 ( ) )
}
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "public key is missing: %s" , err ) )
2020-09-28 11:58:04 +00:00
}
reqID , err := ps . Value ( 1 ) . GetInt ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "request ID is missing: %s" , err ) )
2020-09-28 11:58:04 +00:00
}
txSig , err := ps . Value ( 2 ) . GetBytesBase64 ( )
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , fmt . Sprintf ( "tx signature is missing: %s" , err ) )
2020-09-28 11:58:04 +00:00
}
msgSig , err := ps . Value ( 3 ) . GetBytesBase64 ( )
if err != nil {
2023-08-14 16:43:19 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , fmt . Sprintf ( "msg signature is missing: %s" , err ) )
2020-09-28 11:58:04 +00:00
}
data := broadcaster . GetMessage ( pubBytes , uint64 ( reqID ) , txSig )
if ! pub . Verify ( msgSig , hash . Sha256 ( data ) . BytesBE ( ) ) {
2023-08-14 16:43:19 +00:00
return nil , neorpc . ErrInvalidSignature
2020-09-28 11:58:04 +00:00
}
2023-08-09 12:14:06 +00:00
oracle . AddResponse ( pub , uint64 ( reqID ) , txSig )
2020-09-28 11:58:04 +00:00
return json . RawMessage ( [ ] byte ( "{}" ) ) , nil
}
2023-04-03 10:34:24 +00:00
func ( s * Server ) sendrawtransaction ( reqParams params . Params ) ( any , * neorpc . Error ) {
2019-11-21 14:42:02 +00:00
if len ( reqParams ) < 1 {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( "not enough parameters" )
2021-02-05 07:26:23 +00:00
}
byteTx , err := reqParams [ 0 ] . GetBytesBase64 ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "not a base64: %s" , err ) )
Implement rpc server method: sendrawtransaction (#174)
* Added new config attributes: 'SecondsPerBlock','LowPriorityThreshold'
* Added new files:
* Added new method: CompareTo
* Fixed empty Slice case
* Added new methods: LessThan, GreaterThan, Equal, CompareTo
* Added new method: InputIntersection
* Added MaxTransactionSize, GroupOutputByAssetID
* Added ned method: ScriptHash
* Added new method: IsDoubleSpend
* Refactor blockchainer, Added Feer interface, Verify and GetMemPool method
* 1) Added MemPool
2) Added new methods to satisfy the blockchainer interface: IsLowPriority, Verify, GetMemPool
* Added new methods: RelayTxn, RelayDirectly
* Fixed tests
* Implemented RPC server method sendrawtransaction
* Refactor getrawtransaction, sendrawtransaction in separate methods
* Moved 'secondsPerBlock' to config file
* Implemented Kim suggestions:
1) Fixed data race issues
2) refactor Verify method
3) Get rid of unused InputIntersection method due to refactoring Verify method
4) Fixed bug in https://github.com/CityOfZion/neo-go/pull/174#discussion_r264108135
5) minor simplications of the code
* Fixed minor issues related to
1) space
2) getter methods do not need pointer on the receiver
3) error message
4) refactoring CompareTo method in uint256.go
* Fixed small issues
* Use sync.RWMutex instead of sync.Mutex
* Refined (R)Lock/(R)Unlock
* return error instead of bool in Verify methods
2019-03-20 12:30:05 +00:00
}
2021-03-25 16:18:01 +00:00
tx , err := transaction . NewTransactionFromBytes ( byteTx )
2021-02-05 07:26:23 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInvalidParamsError ( fmt . Sprintf ( "can't decode transaction: %s" , err ) )
2021-02-05 07:26:23 +00:00
}
return getRelayResult ( s . coreServer . RelayTxn ( tx ) , tx . Hash ( ) )
Implement rpc server method: sendrawtransaction (#174)
* Added new config attributes: 'SecondsPerBlock','LowPriorityThreshold'
* Added new files:
* Added new method: CompareTo
* Fixed empty Slice case
* Added new methods: LessThan, GreaterThan, Equal, CompareTo
* Added new method: InputIntersection
* Added MaxTransactionSize, GroupOutputByAssetID
* Added ned method: ScriptHash
* Added new method: IsDoubleSpend
* Refactor blockchainer, Added Feer interface, Verify and GetMemPool method
* 1) Added MemPool
2) Added new methods to satisfy the blockchainer interface: IsLowPriority, Verify, GetMemPool
* Added new methods: RelayTxn, RelayDirectly
* Fixed tests
* Implemented RPC server method sendrawtransaction
* Refactor getrawtransaction, sendrawtransaction in separate methods
* Moved 'secondsPerBlock' to config file
* Implemented Kim suggestions:
1) Fixed data race issues
2) refactor Verify method
3) Get rid of unused InputIntersection method due to refactoring Verify method
4) Fixed bug in https://github.com/CityOfZion/neo-go/pull/174#discussion_r264108135
5) minor simplications of the code
* Fixed minor issues related to
1) space
2) getter methods do not need pointer on the receiver
3) error message
4) refactoring CompareTo method in uint256.go
* Fixed small issues
* Use sync.RWMutex instead of sync.Mutex
* Refined (R)Lock/(R)Unlock
* return error instead of bool in Verify methods
2019-03-20 12:30:05 +00:00
}
2020-05-10 22:00:19 +00:00
// subscribe handles subscription requests from websocket clients.
2023-04-03 10:34:24 +00:00
func ( s * Server ) subscribe ( reqParams params . Params , sub * subscriber ) ( any , * neorpc . Error ) {
2020-06-04 11:58:47 +00:00
streamName , err := reqParams . Value ( 0 ) . GetString ( )
2020-05-10 22:00:19 +00:00
if err != nil {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-05-10 22:00:19 +00:00
}
2022-07-22 16:09:29 +00:00
event , err := neorpc . GetEventIDFromString ( streamName )
if err != nil || event == neorpc . MissedEventID {
return nil , neorpc . ErrInvalidParams
2020-05-10 22:00:19 +00:00
}
2022-07-22 16:09:29 +00:00
if event == neorpc . NotaryRequestEventID && ! s . chain . P2PSigExtensionsEnabled ( ) {
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , "P2PSigExtensions are disabled" )
2021-05-28 11:55:06 +00:00
}
2020-05-13 14:13:33 +00:00
// Optional filter.
2023-12-25 11:14:44 +00:00
var filter neorpc . SubscriptionFilter
2020-06-04 11:58:47 +00:00
if p := reqParams . Value ( 1 ) ; p != nil {
2021-10-28 11:10:18 +00:00
param := * p
jd := json . NewDecoder ( bytes . NewReader ( param . RawMessage ) )
2021-08-05 14:56:17 +00:00
jd . DisallowUnknownFields ( )
2020-05-13 14:13:33 +00:00
switch event {
2023-12-22 08:23:41 +00:00
case neorpc . BlockEventID , neorpc . HeaderOfAddedBlockEventID :
2022-07-22 16:09:29 +00:00
flt := new ( neorpc . BlockFilter )
2021-08-05 14:56:17 +00:00
err = jd . Decode ( flt )
2021-10-28 11:10:18 +00:00
filter = * flt
2023-12-09 08:37:25 +00:00
case neorpc . TransactionEventID :
2022-07-22 16:09:29 +00:00
flt := new ( neorpc . TxFilter )
2021-08-05 14:56:17 +00:00
err = jd . Decode ( flt )
2021-10-28 11:10:18 +00:00
filter = * flt
2023-12-09 08:37:25 +00:00
case neorpc . NotaryRequestEventID :
flt := new ( neorpc . NotaryRequestFilter )
err = jd . Decode ( flt )
filter = * flt
2022-07-22 16:09:29 +00:00
case neorpc . NotificationEventID :
flt := new ( neorpc . NotificationFilter )
2021-08-05 14:56:17 +00:00
err = jd . Decode ( flt )
2021-10-28 11:10:18 +00:00
filter = * flt
2022-07-22 16:09:29 +00:00
case neorpc . ExecutionEventID :
flt := new ( neorpc . ExecutionFilter )
2021-08-05 14:56:17 +00:00
err = jd . Decode ( flt )
2023-12-25 11:14:44 +00:00
filter = * flt
*: fix linter exhaustive errors
```
pkg/smartcontract/rpcbinding/binding.go:523:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/rpcbinding/binding.go:572:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/rpcbinding/binding.go:862:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType, smartcontract.AnyType, smartcontract.BoolType,
smartcontract.IntegerType, smartcontract.ByteArrayType, smartcontract
.Hash160Type, smartcontract.Hash256Type, smartcontract.SignatureType,
smartcontract.InteropInterfaceType, smartcontract.VoidType
pkg/smartcontract/param_type.go:165:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/manifest/permission.go:103:2 exhaustive missing
cases in switch of type manifest.PermissionType: manifest
.PermissionWildcard
pkg/services/notary/core_test.go:223:4 exhaustive missing
cases in switch of type notary.RequestType: notary.Contract
pkg/services/notary/core_test.go:292:4 exhaustive missing
cases in switch of type notary.RequestType: notary.Contract
pkg/services/oracle/jsonpath/jsonpath.go:62:3 exhaustive missing
cases in switch of type jsonpath.pathTokenType: jsonpath.pathInvalid,
jsonpath.pathRoot, jsonpath.pathRightBracket, jsonpath.pathAsterisk,
jsonpath.pathComma, jsonpath.pathColon, jsonpath.pathIdentifier,
jsonpath.pathString, jsonpath.pathNumber
pkg/services/rpcsrv/server.go:2740:3 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/services/rpcsrv/server.go:2804:2 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/services/rpcsrv/server.go:2864:2 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/vm/contract_checks.go:153:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.ENDFINALLY, opcode
.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode
.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK,
opcode.SWAP, opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4,
opcode.REVERSEN, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0,
opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode
.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0,
opcode.NEWARRAY, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP,
opcode.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode
.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS,
opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL,
opcode.ABORTMSG, opcode.ASSERTMSG
pkg/vm/vm.go:912:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALL, opcode.CALLL,
opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW,
opcode.TRY, opcode.TRYL, opcode.ENDTRY, opcode.ENDTRYL, opcode
.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP,
opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode
.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0, opcode
.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode.STSFLD1,
opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode.STSFLD5, opcode
.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2,
opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode.LDLOC6, opcode
.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2, opcode.STLOC3,
opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode.STLOC, opcode
.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3, opcode.LDARG4,
opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode.STARG0, opcode
.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4, opcode.STARG5,
opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode.MEMCPY, opcode
.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode.INVERT, opcode
.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode.NOTEQUAL, opcode
.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode.DEC, opcode.ADD,
opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD, opcode.POW, opcode
.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL, opcode.SHR, opcode
.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode
.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT, opcode.GE, opcode.MIN,
opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode
.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode
.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode
.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM,
opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE,
opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode
.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/vm/vm.go:1116:4 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALL, opcode.CALLL,
opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW,
opcode.TRY, opcode.TRYL, opcode.ENDTRY, opcode.ENDTRYL, opcode
.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP,
opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode
.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode
.INITSLOT, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode
.LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD,
opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode
.STSFLD4, opcode.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0,
opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode
.LDLOC5, opcode.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1,
opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode
.STLOC6, opcode.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2,
opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode
.LDARG, opcode.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3,
opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode
.NEWBUFFER, opcode.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT,
opcode.RIGHT, opcode.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode
.EQUAL, opcode.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE,
opcode.INC, opcode.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode
.DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode
.MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode
.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.MIN,
opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode
.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode
.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode
.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM,
opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE,
opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE,
opcode.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/codegen.go:944:5 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType, smartcontract.AnyType, smartcontract.BoolType,
smartcontract.IntegerType, smartcontract.ByteArrayType, smartcontract
.StringType, smartcontract.PublicKeyType, smartcontract.SignatureType,
smartcontract.ArrayType, smartcontract.MapType, smartcontract
.InteropInterfaceType, smartcontract.VoidType
pkg/compiler/codegen.go:1221:3 exhaustive missing
cases in switch of type token.Token: token.ILLEGAL, token.EOF, token
.COMMENT, token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR,
token.STRING, token.ADD, token.SUB, token.MUL, token.QUO, token.REM,
token.AND, token.OR, token.XOR, token.SHL, token.SHR, token.AND_NOT,
token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN, token.XOR_ASSIGN,
token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN, token.LAND,
token.LOR, token.ARROW, token.INC, token.DEC, token.EQL, token.LSS,
token.GTR, token.ASSIGN, token.NOT, token.NEQ, token.LEQ, token.GEQ,
token.DEFINE, token.ELLIPSIS, token.LPAREN, token.LBRACK, token.LBRACE,
token.COMMA, token.PERIOD, token.RPAREN, token.RBRACK, token.RBRACE,
token.SEMICOLON, token.COLON, token.CASE, token.CHAN, token.CONST, token
.DEFAULT, token.DEFER, token.ELSE, token.FALLTHROUGH, token.FOR, token
.FUNC, token.GO, token.GOTO, token.IF, token.IMPORT, token.INTERFACE,
token.MAP, token.PACKAGE, token.RANGE, token.RETURN, token.SELECT, token
.STRUCT, token.SWITCH, token.TYPE, token.VAR, token.TILDE
pkg/compiler/codegen.go:1709:2 exhaustive missing
cases in switch of type token.Token: token.ILLEGAL, token.EOF, token
.COMMENT, token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR,
token.STRING, token.ADD, token.SUB, token.MUL, token.QUO, token.REM,
token.AND, token.OR, token.XOR, token.SHL, token.SHR, token.AND_NOT,
token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN, token.XOR_ASSIGN,
token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN, token.LAND,
token.LOR, token.ARROW, token.INC, token.DEC, token.ASSIGN, token.NOT,
token.DEFINE, token.ELLIPSIS, token.LPAREN, token.LBRACK, token.LBRACE,
token.COMMA, token.PERIOD, token.RPAREN, token.RBRACK, token.RBRACE,
token.SEMICOLON, token.COLON, token.BREAK, token.CASE, token.CHAN, token
.CONST, token.CONTINUE, token.DEFAULT, token.DEFER, token.ELSE, token
.FALLTHROUGH, token.FOR, token.FUNC, token.GO, token.GOTO, token.IF,
token.IMPORT, token.INTERFACE, token.MAP, token.PACKAGE, token.RANGE,
token.RETURN, token.SELECT, token.STRUCT, token.SWITCH, token.TYPE,
token.VAR, token.TILDE
pkg/compiler/codegen.go:2353:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.ENDTRY,
opcode.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode
.DROP, opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER,
opcode.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode
.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode
.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0,
opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode
.NEWARRAY, opcode.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT,
opcode.NEWMAP, opcode.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES,
opcode.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS,
opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode
.ISTYPE, opcode.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/codegen.go:2474:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.ENDFINALLY, opcode
.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode
.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK,
opcode.SWAP, opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4,
opcode.REVERSEN, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0,
opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode
.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0,
opcode.NEWARRAY, opcode.NEWARRAYT, opcode.NEWSTRUCT0, opcode
.NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode.HASKEY, opcode.KEYS,
opcode.VALUES, opcode.PICKITEM, opcode.APPEND, opcode.SETITEM,
opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS, opcode
.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode.CONVERT, opcode
.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/inline_test.go:34:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.TRYL,
opcode.ENDTRY, opcode.ENDTRYL, opcode.ENDFINALLY, opcode.RET, opcode
.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode.XDROP, opcode
.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK, opcode.SWAP,
opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4, opcode
.REVERSEN, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode
.LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD,
opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode
.STSFLD4, opcode.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0,
opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode
.LDLOC5, opcode.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1,
opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode
.STLOC6, opcode.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2,
opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode
.LDARG, opcode.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3,
opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode
.NEWBUFFER, opcode.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT,
opcode.RIGHT, opcode.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode
.EQUAL, opcode.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE,
opcode.INC, opcode.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode
.DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode
.MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode
.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT,
opcode.LE, opcode.GT, opcode.GE, opcode.MIN, opcode.MAX, opcode
.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode.PACK, opcode
.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode.NEWARRAYT, opcode
.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode
.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM, opcode.APPEND,
opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS,
opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode.CONVERT, opcode
.ABORTMSG, opcode.ASSERTMSG
pkg/network/server.go:1395:3 exhaustive missing
cases in switch of type network.CommandType: network.CMDNotFound,
network.CMDReject, network.CMDFilterLoad, network.CMDFilterAdd, network
.CMDFilterClear, network.CMDMerkleBlock, network.CMDAlert
pkg/network/server_test.go:532:3 exhaustive missing
cases in switch of type network.CommandType: network.CMDVersion, network
.CMDVerack, network.CMDGetAddr, network.CMDAddr, network.CMDPing,
network.CMDPong, network.CMDGetHeaders, network.CMDHeaders, network
.CMDGetBlocks, network.CMDMempool, network.CMDInv, network.CMDGetData,
network.CMDGetBlockByIndex, network.CMDGetMPTData, network.CMDMPTData,
network.CMDReject, network.CMDFilterLoad, network.CMDFilterAdd, network
.CMDFilterClear, network.CMDMerkleBlock, network.CMDAlert
pkg/network/server_test.go:817:4 exhaustive missing
cases in switch of type network.CommandType: network.CMDVersion, network
.CMDVerack, network.CMDGetAddr, network.CMDAddr, network.CMDPing,
network.CMDPong, network.CMDGetHeaders, network.CMDHeaders, network
.CMDGetBlocks, network.CMDMempool, network.CMDInv, network.CMDGetData,
network.CMDGetBlockByIndex, network.CMDNotFound, network.CMDTX, network
.CMDBlock, network.CMDExtensible, network.CMDP2PNotaryRequest, network
.CMDGetMPTData, network.CMDReject, network.CMDFilterLoad, network
.CMDFilterAdd, network.CMDFilterClear, network.CMDMerkleBlock, network
.CMDAlert
pkg/core/native/designate.go:262:2 exhaustive missing
cases in switch of type noderoles.Role: noderoles.NeoFSAlphabet
pkg/neorpc/rpcevent/filter.go:36:2 exhaustive missing cases in switch
of type neorpc.EventID: neorpc.InvalidEventID, neorpc.MissedEventID
pkg/consensus/recovery_message.go:145:2 exhaustive missing
cases in switch of type dbft.MessageType: dbft.PreCommitType, dbft
.RecoveryRequestType, dbft.RecoveryMessageType
cli/cmdargs/parser.go:202:3 exhaustive missing cases in switch of type
transaction.WitnessScope: transaction.None, transaction.CalledByEntry,
transaction.Rules, transaction.Global
```
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-09-26 08:30:54 +00:00
default :
2023-12-25 11:14:44 +00:00
}
if err != nil {
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , err . Error ( ) )
2020-05-13 14:13:33 +00:00
}
2023-12-25 11:14:44 +00:00
}
if filter != nil {
err = filter . IsValid ( )
2021-08-05 14:56:17 +00:00
if err != nil {
2022-11-16 09:37:18 +00:00
return nil , neorpc . WrapErrorWithData ( neorpc . ErrInvalidParams , err . Error ( ) )
2021-08-05 14:56:17 +00:00
}
2020-05-13 14:13:33 +00:00
}
2020-05-10 22:00:19 +00:00
s . subsLock . Lock ( )
var id int
for ; id < len ( sub . feeds ) ; id ++ {
2022-07-22 16:09:29 +00:00
if sub . feeds [ id ] . event == neorpc . InvalidEventID {
2020-05-10 22:00:19 +00:00
break
}
}
if id == len ( sub . feeds ) {
2022-11-17 13:00:22 +00:00
s . subsLock . Unlock ( )
2022-07-22 16:09:29 +00:00
return nil , neorpc . NewInternalServerError ( "maximum number of subscriptions is reached" )
2020-05-10 22:00:19 +00:00
}
2020-05-13 14:13:33 +00:00
sub . feeds [ id ] . event = event
sub . feeds [ id ] . filter = filter
2022-11-17 13:00:22 +00:00
s . subsLock . Unlock ( )
s . subsCounterLock . Lock ( )
2022-11-18 07:40:28 +00:00
select {
case <- s . shutdown :
s . subsCounterLock . Unlock ( )
return nil , neorpc . NewInternalServerError ( "server is shutting down" )
default :
}
2020-05-10 22:00:19 +00:00
s . subscribeToChannel ( event )
2022-11-17 13:00:22 +00:00
s . subsCounterLock . Unlock ( )
2020-05-10 22:00:19 +00:00
return strconv . FormatInt ( int64 ( id ) , 10 ) , nil
}
// subscribeToChannel subscribes RPC server to appropriate chain events if
2022-11-17 13:00:22 +00:00
// it's not yet subscribed for them. It's supposed to be called with s.subsCounterLock
2020-05-10 22:00:19 +00:00
// taken by the caller.
2022-07-22 16:09:29 +00:00
func ( s * Server ) subscribeToChannel ( event neorpc . EventID ) {
2020-05-10 22:00:19 +00:00
switch event {
2022-07-22 16:09:29 +00:00
case neorpc . BlockEventID :
2020-05-10 22:00:19 +00:00
if s . blockSubs == 0 {
s . chain . SubscribeForBlocks ( s . blockCh )
}
s . blockSubs ++
2022-07-22 16:09:29 +00:00
case neorpc . TransactionEventID :
2020-05-10 22:00:19 +00:00
if s . transactionSubs == 0 {
s . chain . SubscribeForTransactions ( s . transactionCh )
}
s . transactionSubs ++
2022-07-22 16:09:29 +00:00
case neorpc . NotificationEventID :
2020-05-10 22:00:19 +00:00
if s . notificationSubs == 0 {
s . chain . SubscribeForNotifications ( s . notificationCh )
}
s . notificationSubs ++
2022-07-22 16:09:29 +00:00
case neorpc . ExecutionEventID :
2020-05-10 22:00:19 +00:00
if s . executionSubs == 0 {
s . chain . SubscribeForExecutions ( s . executionCh )
}
s . executionSubs ++
2022-07-22 16:09:29 +00:00
case neorpc . NotaryRequestEventID :
2021-05-28 11:55:06 +00:00
if s . notaryRequestSubs == 0 {
s . coreServer . SubscribeForNotaryRequests ( s . notaryRequestCh )
}
s . notaryRequestSubs ++
2023-12-22 08:23:41 +00:00
case neorpc . HeaderOfAddedBlockEventID :
if s . blockHeaderSubs == 0 {
s . chain . SubscribeForHeadersOfAddedBlocks ( s . blockHeaderCh )
}
s . blockHeaderSubs ++
*: fix linter exhaustive errors
```
pkg/smartcontract/rpcbinding/binding.go:523:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/rpcbinding/binding.go:572:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/rpcbinding/binding.go:862:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType, smartcontract.AnyType, smartcontract.BoolType,
smartcontract.IntegerType, smartcontract.ByteArrayType, smartcontract
.Hash160Type, smartcontract.Hash256Type, smartcontract.SignatureType,
smartcontract.InteropInterfaceType, smartcontract.VoidType
pkg/smartcontract/param_type.go:165:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/manifest/permission.go:103:2 exhaustive missing
cases in switch of type manifest.PermissionType: manifest
.PermissionWildcard
pkg/services/notary/core_test.go:223:4 exhaustive missing
cases in switch of type notary.RequestType: notary.Contract
pkg/services/notary/core_test.go:292:4 exhaustive missing
cases in switch of type notary.RequestType: notary.Contract
pkg/services/oracle/jsonpath/jsonpath.go:62:3 exhaustive missing
cases in switch of type jsonpath.pathTokenType: jsonpath.pathInvalid,
jsonpath.pathRoot, jsonpath.pathRightBracket, jsonpath.pathAsterisk,
jsonpath.pathComma, jsonpath.pathColon, jsonpath.pathIdentifier,
jsonpath.pathString, jsonpath.pathNumber
pkg/services/rpcsrv/server.go:2740:3 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/services/rpcsrv/server.go:2804:2 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/services/rpcsrv/server.go:2864:2 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/vm/contract_checks.go:153:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.ENDFINALLY, opcode
.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode
.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK,
opcode.SWAP, opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4,
opcode.REVERSEN, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0,
opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode
.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0,
opcode.NEWARRAY, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP,
opcode.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode
.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS,
opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL,
opcode.ABORTMSG, opcode.ASSERTMSG
pkg/vm/vm.go:912:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALL, opcode.CALLL,
opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW,
opcode.TRY, opcode.TRYL, opcode.ENDTRY, opcode.ENDTRYL, opcode
.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP,
opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode
.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0, opcode
.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode.STSFLD1,
opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode.STSFLD5, opcode
.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2,
opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode.LDLOC6, opcode
.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2, opcode.STLOC3,
opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode.STLOC, opcode
.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3, opcode.LDARG4,
opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode.STARG0, opcode
.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4, opcode.STARG5,
opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode.MEMCPY, opcode
.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode.INVERT, opcode
.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode.NOTEQUAL, opcode
.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode.DEC, opcode.ADD,
opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD, opcode.POW, opcode
.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL, opcode.SHR, opcode
.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode
.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT, opcode.GE, opcode.MIN,
opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode
.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode
.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode
.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM,
opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE,
opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode
.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/vm/vm.go:1116:4 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALL, opcode.CALLL,
opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW,
opcode.TRY, opcode.TRYL, opcode.ENDTRY, opcode.ENDTRYL, opcode
.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP,
opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode
.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode
.INITSLOT, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode
.LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD,
opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode
.STSFLD4, opcode.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0,
opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode
.LDLOC5, opcode.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1,
opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode
.STLOC6, opcode.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2,
opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode
.LDARG, opcode.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3,
opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode
.NEWBUFFER, opcode.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT,
opcode.RIGHT, opcode.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode
.EQUAL, opcode.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE,
opcode.INC, opcode.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode
.DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode
.MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode
.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.MIN,
opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode
.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode
.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode
.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM,
opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE,
opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE,
opcode.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/codegen.go:944:5 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType, smartcontract.AnyType, smartcontract.BoolType,
smartcontract.IntegerType, smartcontract.ByteArrayType, smartcontract
.StringType, smartcontract.PublicKeyType, smartcontract.SignatureType,
smartcontract.ArrayType, smartcontract.MapType, smartcontract
.InteropInterfaceType, smartcontract.VoidType
pkg/compiler/codegen.go:1221:3 exhaustive missing
cases in switch of type token.Token: token.ILLEGAL, token.EOF, token
.COMMENT, token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR,
token.STRING, token.ADD, token.SUB, token.MUL, token.QUO, token.REM,
token.AND, token.OR, token.XOR, token.SHL, token.SHR, token.AND_NOT,
token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN, token.XOR_ASSIGN,
token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN, token.LAND,
token.LOR, token.ARROW, token.INC, token.DEC, token.EQL, token.LSS,
token.GTR, token.ASSIGN, token.NOT, token.NEQ, token.LEQ, token.GEQ,
token.DEFINE, token.ELLIPSIS, token.LPAREN, token.LBRACK, token.LBRACE,
token.COMMA, token.PERIOD, token.RPAREN, token.RBRACK, token.RBRACE,
token.SEMICOLON, token.COLON, token.CASE, token.CHAN, token.CONST, token
.DEFAULT, token.DEFER, token.ELSE, token.FALLTHROUGH, token.FOR, token
.FUNC, token.GO, token.GOTO, token.IF, token.IMPORT, token.INTERFACE,
token.MAP, token.PACKAGE, token.RANGE, token.RETURN, token.SELECT, token
.STRUCT, token.SWITCH, token.TYPE, token.VAR, token.TILDE
pkg/compiler/codegen.go:1709:2 exhaustive missing
cases in switch of type token.Token: token.ILLEGAL, token.EOF, token
.COMMENT, token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR,
token.STRING, token.ADD, token.SUB, token.MUL, token.QUO, token.REM,
token.AND, token.OR, token.XOR, token.SHL, token.SHR, token.AND_NOT,
token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN, token.XOR_ASSIGN,
token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN, token.LAND,
token.LOR, token.ARROW, token.INC, token.DEC, token.ASSIGN, token.NOT,
token.DEFINE, token.ELLIPSIS, token.LPAREN, token.LBRACK, token.LBRACE,
token.COMMA, token.PERIOD, token.RPAREN, token.RBRACK, token.RBRACE,
token.SEMICOLON, token.COLON, token.BREAK, token.CASE, token.CHAN, token
.CONST, token.CONTINUE, token.DEFAULT, token.DEFER, token.ELSE, token
.FALLTHROUGH, token.FOR, token.FUNC, token.GO, token.GOTO, token.IF,
token.IMPORT, token.INTERFACE, token.MAP, token.PACKAGE, token.RANGE,
token.RETURN, token.SELECT, token.STRUCT, token.SWITCH, token.TYPE,
token.VAR, token.TILDE
pkg/compiler/codegen.go:2353:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.ENDTRY,
opcode.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode
.DROP, opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER,
opcode.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode
.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode
.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0,
opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode
.NEWARRAY, opcode.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT,
opcode.NEWMAP, opcode.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES,
opcode.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS,
opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode
.ISTYPE, opcode.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/codegen.go:2474:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.ENDFINALLY, opcode
.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode
.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK,
opcode.SWAP, opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4,
opcode.REVERSEN, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0,
opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode
.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0,
opcode.NEWARRAY, opcode.NEWARRAYT, opcode.NEWSTRUCT0, opcode
.NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode.HASKEY, opcode.KEYS,
opcode.VALUES, opcode.PICKITEM, opcode.APPEND, opcode.SETITEM,
opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS, opcode
.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode.CONVERT, opcode
.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/inline_test.go:34:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.TRYL,
opcode.ENDTRY, opcode.ENDTRYL, opcode.ENDFINALLY, opcode.RET, opcode
.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode.XDROP, opcode
.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK, opcode.SWAP,
opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4, opcode
.REVERSEN, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode
.LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD,
opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode
.STSFLD4, opcode.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0,
opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode
.LDLOC5, opcode.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1,
opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode
.STLOC6, opcode.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2,
opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode
.LDARG, opcode.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3,
opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode
.NEWBUFFER, opcode.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT,
opcode.RIGHT, opcode.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode
.EQUAL, opcode.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE,
opcode.INC, opcode.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode
.DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode
.MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode
.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT,
opcode.LE, opcode.GT, opcode.GE, opcode.MIN, opcode.MAX, opcode
.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode.PACK, opcode
.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode.NEWARRAYT, opcode
.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode
.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM, opcode.APPEND,
opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS,
opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode.CONVERT, opcode
.ABORTMSG, opcode.ASSERTMSG
pkg/network/server.go:1395:3 exhaustive missing
cases in switch of type network.CommandType: network.CMDNotFound,
network.CMDReject, network.CMDFilterLoad, network.CMDFilterAdd, network
.CMDFilterClear, network.CMDMerkleBlock, network.CMDAlert
pkg/network/server_test.go:532:3 exhaustive missing
cases in switch of type network.CommandType: network.CMDVersion, network
.CMDVerack, network.CMDGetAddr, network.CMDAddr, network.CMDPing,
network.CMDPong, network.CMDGetHeaders, network.CMDHeaders, network
.CMDGetBlocks, network.CMDMempool, network.CMDInv, network.CMDGetData,
network.CMDGetBlockByIndex, network.CMDGetMPTData, network.CMDMPTData,
network.CMDReject, network.CMDFilterLoad, network.CMDFilterAdd, network
.CMDFilterClear, network.CMDMerkleBlock, network.CMDAlert
pkg/network/server_test.go:817:4 exhaustive missing
cases in switch of type network.CommandType: network.CMDVersion, network
.CMDVerack, network.CMDGetAddr, network.CMDAddr, network.CMDPing,
network.CMDPong, network.CMDGetHeaders, network.CMDHeaders, network
.CMDGetBlocks, network.CMDMempool, network.CMDInv, network.CMDGetData,
network.CMDGetBlockByIndex, network.CMDNotFound, network.CMDTX, network
.CMDBlock, network.CMDExtensible, network.CMDP2PNotaryRequest, network
.CMDGetMPTData, network.CMDReject, network.CMDFilterLoad, network
.CMDFilterAdd, network.CMDFilterClear, network.CMDMerkleBlock, network
.CMDAlert
pkg/core/native/designate.go:262:2 exhaustive missing
cases in switch of type noderoles.Role: noderoles.NeoFSAlphabet
pkg/neorpc/rpcevent/filter.go:36:2 exhaustive missing cases in switch
of type neorpc.EventID: neorpc.InvalidEventID, neorpc.MissedEventID
pkg/consensus/recovery_message.go:145:2 exhaustive missing
cases in switch of type dbft.MessageType: dbft.PreCommitType, dbft
.RecoveryRequestType, dbft.RecoveryMessageType
cli/cmdargs/parser.go:202:3 exhaustive missing cases in switch of type
transaction.WitnessScope: transaction.None, transaction.CalledByEntry,
transaction.Rules, transaction.Global
```
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-09-26 08:30:54 +00:00
default :
2020-05-10 22:00:19 +00:00
}
}
// unsubscribe handles unsubscription requests from websocket clients.
2023-04-03 10:34:24 +00:00
func ( s * Server ) unsubscribe ( reqParams params . Params , sub * subscriber ) ( any , * neorpc . Error ) {
2020-06-04 11:58:47 +00:00
id , err := reqParams . Value ( 0 ) . GetInt ( )
2020-05-10 22:00:19 +00:00
if err != nil || id < 0 {
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-05-10 22:00:19 +00:00
}
s . subsLock . Lock ( )
2022-07-22 16:09:29 +00:00
if len ( sub . feeds ) <= id || sub . feeds [ id ] . event == neorpc . InvalidEventID {
2022-11-17 13:00:22 +00:00
s . subsLock . Unlock ( )
2022-07-22 16:09:29 +00:00
return nil , neorpc . ErrInvalidParams
2020-05-10 22:00:19 +00:00
}
2020-05-13 14:13:33 +00:00
event := sub . feeds [ id ] . event
2022-07-22 16:09:29 +00:00
sub . feeds [ id ] . event = neorpc . InvalidEventID
2020-05-13 14:13:33 +00:00
sub . feeds [ id ] . filter = nil
2022-11-17 13:00:22 +00:00
s . subsLock . Unlock ( )
s . subsCounterLock . Lock ( )
2020-05-10 22:00:19 +00:00
s . unsubscribeFromChannel ( event )
2022-11-17 13:00:22 +00:00
s . subsCounterLock . Unlock ( )
2020-05-10 22:00:19 +00:00
return true , nil
}
// unsubscribeFromChannel unsubscribes RPC server from appropriate chain events
2022-11-17 13:00:22 +00:00
// if there are no other subscribers for it. It must be called with s.subsConutersLock
// holding by the caller.
2022-07-22 16:09:29 +00:00
func ( s * Server ) unsubscribeFromChannel ( event neorpc . EventID ) {
2020-05-10 22:00:19 +00:00
switch event {
2022-07-22 16:09:29 +00:00
case neorpc . BlockEventID :
2020-05-10 22:00:19 +00:00
s . blockSubs --
if s . blockSubs == 0 {
s . chain . UnsubscribeFromBlocks ( s . blockCh )
}
2022-07-22 16:09:29 +00:00
case neorpc . TransactionEventID :
2020-05-10 22:00:19 +00:00
s . transactionSubs --
if s . transactionSubs == 0 {
s . chain . UnsubscribeFromTransactions ( s . transactionCh )
}
2022-07-22 16:09:29 +00:00
case neorpc . NotificationEventID :
2020-05-10 22:00:19 +00:00
s . notificationSubs --
if s . notificationSubs == 0 {
s . chain . UnsubscribeFromNotifications ( s . notificationCh )
}
2022-07-22 16:09:29 +00:00
case neorpc . ExecutionEventID :
2020-05-10 22:00:19 +00:00
s . executionSubs --
if s . executionSubs == 0 {
s . chain . UnsubscribeFromExecutions ( s . executionCh )
}
2022-07-22 16:09:29 +00:00
case neorpc . NotaryRequestEventID :
2021-05-28 11:55:06 +00:00
s . notaryRequestSubs --
if s . notaryRequestSubs == 0 {
s . coreServer . UnsubscribeFromNotaryRequests ( s . notaryRequestCh )
}
2023-12-22 08:23:41 +00:00
case neorpc . HeaderOfAddedBlockEventID :
s . blockHeaderSubs --
if s . blockHeaderSubs == 0 {
s . chain . UnsubscribeFromHeadersOfAddedBlocks ( s . blockHeaderCh )
}
*: fix linter exhaustive errors
```
pkg/smartcontract/rpcbinding/binding.go:523:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/rpcbinding/binding.go:572:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/rpcbinding/binding.go:862:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType, smartcontract.AnyType, smartcontract.BoolType,
smartcontract.IntegerType, smartcontract.ByteArrayType, smartcontract
.Hash160Type, smartcontract.Hash256Type, smartcontract.SignatureType,
smartcontract.InteropInterfaceType, smartcontract.VoidType
pkg/smartcontract/param_type.go:165:2 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType
pkg/smartcontract/manifest/permission.go:103:2 exhaustive missing
cases in switch of type manifest.PermissionType: manifest
.PermissionWildcard
pkg/services/notary/core_test.go:223:4 exhaustive missing
cases in switch of type notary.RequestType: notary.Contract
pkg/services/notary/core_test.go:292:4 exhaustive missing
cases in switch of type notary.RequestType: notary.Contract
pkg/services/oracle/jsonpath/jsonpath.go:62:3 exhaustive missing
cases in switch of type jsonpath.pathTokenType: jsonpath.pathInvalid,
jsonpath.pathRoot, jsonpath.pathRightBracket, jsonpath.pathAsterisk,
jsonpath.pathComma, jsonpath.pathColon, jsonpath.pathIdentifier,
jsonpath.pathString, jsonpath.pathNumber
pkg/services/rpcsrv/server.go:2740:3 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/services/rpcsrv/server.go:2804:2 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/services/rpcsrv/server.go:2864:2 exhaustive missing
cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc
.MissedEventID
pkg/vm/contract_checks.go:153:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.ENDFINALLY, opcode
.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode
.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK,
opcode.SWAP, opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4,
opcode.REVERSEN, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0,
opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode
.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0,
opcode.NEWARRAY, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP,
opcode.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode
.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS,
opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL,
opcode.ABORTMSG, opcode.ASSERTMSG
pkg/vm/vm.go:912:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALL, opcode.CALLL,
opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW,
opcode.TRY, opcode.TRYL, opcode.ENDTRY, opcode.ENDTRYL, opcode
.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP,
opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode
.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0, opcode
.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode.STSFLD1,
opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode.STSFLD5, opcode
.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2,
opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode.LDLOC6, opcode
.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2, opcode.STLOC3,
opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode.STLOC, opcode
.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3, opcode.LDARG4,
opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode.STARG0, opcode
.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4, opcode.STARG5,
opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode.MEMCPY, opcode
.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode.INVERT, opcode
.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode.NOTEQUAL, opcode
.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode.DEC, opcode.ADD,
opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD, opcode.POW, opcode
.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL, opcode.SHR, opcode
.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode
.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT, opcode.GE, opcode.MIN,
opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode
.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode
.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode
.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM,
opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE,
opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode
.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/vm/vm.go:1116:4 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALL, opcode.CALLL,
opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW,
opcode.TRY, opcode.TRYL, opcode.ENDTRY, opcode.ENDTRYL, opcode
.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP,
opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode
.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode
.INITSLOT, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode
.LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD,
opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode
.STSFLD4, opcode.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0,
opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode
.LDLOC5, opcode.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1,
opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode
.STLOC6, opcode.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2,
opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode
.LDARG, opcode.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3,
opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode
.NEWBUFFER, opcode.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT,
opcode.RIGHT, opcode.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode
.EQUAL, opcode.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE,
opcode.INC, opcode.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode
.DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode
.MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode
.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.MIN,
opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode
.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode
.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode
.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM,
opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE,
opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE,
opcode.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/codegen.go:944:5 exhaustive missing
cases in switch of type smartcontract.ParamType: smartcontract
.UnknownType, smartcontract.AnyType, smartcontract.BoolType,
smartcontract.IntegerType, smartcontract.ByteArrayType, smartcontract
.StringType, smartcontract.PublicKeyType, smartcontract.SignatureType,
smartcontract.ArrayType, smartcontract.MapType, smartcontract
.InteropInterfaceType, smartcontract.VoidType
pkg/compiler/codegen.go:1221:3 exhaustive missing
cases in switch of type token.Token: token.ILLEGAL, token.EOF, token
.COMMENT, token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR,
token.STRING, token.ADD, token.SUB, token.MUL, token.QUO, token.REM,
token.AND, token.OR, token.XOR, token.SHL, token.SHR, token.AND_NOT,
token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN, token.XOR_ASSIGN,
token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN, token.LAND,
token.LOR, token.ARROW, token.INC, token.DEC, token.EQL, token.LSS,
token.GTR, token.ASSIGN, token.NOT, token.NEQ, token.LEQ, token.GEQ,
token.DEFINE, token.ELLIPSIS, token.LPAREN, token.LBRACK, token.LBRACE,
token.COMMA, token.PERIOD, token.RPAREN, token.RBRACK, token.RBRACE,
token.SEMICOLON, token.COLON, token.CASE, token.CHAN, token.CONST, token
.DEFAULT, token.DEFER, token.ELSE, token.FALLTHROUGH, token.FOR, token
.FUNC, token.GO, token.GOTO, token.IF, token.IMPORT, token.INTERFACE,
token.MAP, token.PACKAGE, token.RANGE, token.RETURN, token.SELECT, token
.STRUCT, token.SWITCH, token.TYPE, token.VAR, token.TILDE
pkg/compiler/codegen.go:1709:2 exhaustive missing
cases in switch of type token.Token: token.ILLEGAL, token.EOF, token
.COMMENT, token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR,
token.STRING, token.ADD, token.SUB, token.MUL, token.QUO, token.REM,
token.AND, token.OR, token.XOR, token.SHL, token.SHR, token.AND_NOT,
token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN, token.XOR_ASSIGN,
token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN, token.LAND,
token.LOR, token.ARROW, token.INC, token.DEC, token.ASSIGN, token.NOT,
token.DEFINE, token.ELLIPSIS, token.LPAREN, token.LBRACK, token.LBRACE,
token.COMMA, token.PERIOD, token.RPAREN, token.RBRACK, token.RBRACE,
token.SEMICOLON, token.COLON, token.BREAK, token.CASE, token.CHAN, token
.CONST, token.CONTINUE, token.DEFAULT, token.DEFER, token.ELSE, token
.FALLTHROUGH, token.FOR, token.FUNC, token.GO, token.GOTO, token.IF,
token.IMPORT, token.INTERFACE, token.MAP, token.PACKAGE, token.RANGE,
token.RETURN, token.SELECT, token.STRUCT, token.SWITCH, token.TYPE,
token.VAR, token.TILDE
pkg/compiler/codegen.go:2353:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.ENDTRY,
opcode.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode
.DROP, opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER,
opcode.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode
.REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode
.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode
.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0,
opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode
.NEWARRAY, opcode.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT,
opcode.NEWMAP, opcode.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES,
opcode.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS,
opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode
.ISTYPE, opcode.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/codegen.go:2474:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode
.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode
.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode
.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode
.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14,
opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.ENDFINALLY, opcode
.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode
.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK,
opcode.SWAP, opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4,
opcode.REVERSEN, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0,
opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode
.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode
.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode
.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1,
opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode
.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2,
opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode
.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3,
opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode
.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4,
opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode
.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode
.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode
.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode
.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD,
opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL,
opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ,
opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT,
opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP,
opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0,
opcode.NEWARRAY, opcode.NEWARRAYT, opcode.NEWSTRUCT0, opcode
.NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode.HASKEY, opcode.KEYS,
opcode.VALUES, opcode.PICKITEM, opcode.APPEND, opcode.SETITEM,
opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS, opcode
.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode.CONVERT, opcode
.ABORTMSG, opcode.ASSERTMSG
pkg/compiler/inline_test.go:34:3 exhaustive missing
cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode
.PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128,
opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode
.PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode
.PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode
.PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode
.PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13,
opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP,
opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode
.JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL,
opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT,
opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALLA, opcode.CALLT,
opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.TRYL,
opcode.ENDTRY, opcode.ENDTRYL, opcode.ENDFINALLY, opcode.RET, opcode
.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode.XDROP, opcode
.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK, opcode.SWAP,
opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4, opcode
.REVERSEN, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode
.LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD,
opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode
.STSFLD4, opcode.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0,
opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode
.LDLOC5, opcode.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1,
opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode
.STLOC6, opcode.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2,
opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode
.LDARG, opcode.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3,
opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode
.NEWBUFFER, opcode.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT,
opcode.RIGHT, opcode.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode
.EQUAL, opcode.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE,
opcode.INC, opcode.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode
.DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode
.MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode
.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT,
opcode.LE, opcode.GT, opcode.GE, opcode.MIN, opcode.MAX, opcode
.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode.PACK, opcode
.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode.NEWARRAYT, opcode
.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode
.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM, opcode.APPEND,
opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS,
opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode.CONVERT, opcode
.ABORTMSG, opcode.ASSERTMSG
pkg/network/server.go:1395:3 exhaustive missing
cases in switch of type network.CommandType: network.CMDNotFound,
network.CMDReject, network.CMDFilterLoad, network.CMDFilterAdd, network
.CMDFilterClear, network.CMDMerkleBlock, network.CMDAlert
pkg/network/server_test.go:532:3 exhaustive missing
cases in switch of type network.CommandType: network.CMDVersion, network
.CMDVerack, network.CMDGetAddr, network.CMDAddr, network.CMDPing,
network.CMDPong, network.CMDGetHeaders, network.CMDHeaders, network
.CMDGetBlocks, network.CMDMempool, network.CMDInv, network.CMDGetData,
network.CMDGetBlockByIndex, network.CMDGetMPTData, network.CMDMPTData,
network.CMDReject, network.CMDFilterLoad, network.CMDFilterAdd, network
.CMDFilterClear, network.CMDMerkleBlock, network.CMDAlert
pkg/network/server_test.go:817:4 exhaustive missing
cases in switch of type network.CommandType: network.CMDVersion, network
.CMDVerack, network.CMDGetAddr, network.CMDAddr, network.CMDPing,
network.CMDPong, network.CMDGetHeaders, network.CMDHeaders, network
.CMDGetBlocks, network.CMDMempool, network.CMDInv, network.CMDGetData,
network.CMDGetBlockByIndex, network.CMDNotFound, network.CMDTX, network
.CMDBlock, network.CMDExtensible, network.CMDP2PNotaryRequest, network
.CMDGetMPTData, network.CMDReject, network.CMDFilterLoad, network
.CMDFilterAdd, network.CMDFilterClear, network.CMDMerkleBlock, network
.CMDAlert
pkg/core/native/designate.go:262:2 exhaustive missing
cases in switch of type noderoles.Role: noderoles.NeoFSAlphabet
pkg/neorpc/rpcevent/filter.go:36:2 exhaustive missing cases in switch
of type neorpc.EventID: neorpc.InvalidEventID, neorpc.MissedEventID
pkg/consensus/recovery_message.go:145:2 exhaustive missing
cases in switch of type dbft.MessageType: dbft.PreCommitType, dbft
.RecoveryRequestType, dbft.RecoveryMessageType
cli/cmdargs/parser.go:202:3 exhaustive missing cases in switch of type
transaction.WitnessScope: transaction.None, transaction.CalledByEntry,
transaction.Rules, transaction.Global
```
Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
2024-09-26 08:30:54 +00:00
default :
2020-05-10 22:00:19 +00:00
}
}
2023-04-13 08:36:39 +00:00
// handleSubEvents processes Server subscriptions until Shutdown. Upon
// completion signals to subEventCh channel.
2020-05-10 22:00:19 +00:00
func ( s * Server ) handleSubEvents ( ) {
2023-02-15 07:07:47 +00:00
var overflowEvent = neorpc . Notification {
2022-07-22 16:09:29 +00:00
JSONRPC : neorpc . JSONRPCVersion ,
Event : neorpc . MissedEventID ,
2023-04-03 10:34:24 +00:00
Payload : make ( [ ] any , 0 ) ,
2023-02-15 07:07:47 +00:00
}
b , err := json . Marshal ( overflowEvent )
2020-05-12 19:38:29 +00:00
if err != nil {
s . log . Error ( "fatal: failed to marshal overflow event" , zap . Error ( err ) )
return
}
overflowMsg , err := websocket . NewPreparedMessage ( websocket . TextMessage , b )
if err != nil {
s . log . Error ( "fatal: failed to prepare overflow message" , zap . Error ( err ) )
return
}
2020-05-10 22:00:19 +00:00
chloop :
for {
2022-07-22 16:09:29 +00:00
var resp = neorpc . Notification {
JSONRPC : neorpc . JSONRPCVersion ,
2023-04-03 10:34:24 +00:00
Payload : make ( [ ] any , 1 ) ,
2020-05-10 22:00:19 +00:00
}
var msg * websocket . PreparedMessage
select {
case <- s . shutdown :
break chloop
case b := <- s . blockCh :
2022-07-22 16:09:29 +00:00
resp . Event = neorpc . BlockEventID
2020-05-10 22:00:19 +00:00
resp . Payload [ 0 ] = b
case execution := <- s . executionCh :
2022-07-22 16:09:29 +00:00
resp . Event = neorpc . ExecutionEventID
2020-09-03 16:58:50 +00:00
resp . Payload [ 0 ] = execution
2020-05-10 22:00:19 +00:00
case notification := <- s . notificationCh :
2022-07-22 16:09:29 +00:00
resp . Event = neorpc . NotificationEventID
2020-10-19 10:44:20 +00:00
resp . Payload [ 0 ] = notification
2020-05-10 22:00:19 +00:00
case tx := <- s . transactionCh :
2022-07-22 16:09:29 +00:00
resp . Event = neorpc . TransactionEventID
2020-05-10 22:00:19 +00:00
resp . Payload [ 0 ] = tx
2021-05-28 11:55:06 +00:00
case e := <- s . notaryRequestCh :
2022-07-22 16:09:29 +00:00
resp . Event = neorpc . NotaryRequestEventID
2022-07-22 18:26:29 +00:00
resp . Payload [ 0 ] = & result . NotaryRequestEvent {
2021-05-28 11:55:06 +00:00
Type : e . Type ,
NotaryRequest : e . Data . ( * payload . P2PNotaryRequest ) ,
}
2023-12-22 08:23:41 +00:00
case header := <- s . blockHeaderCh :
resp . Event = neorpc . HeaderOfAddedBlockEventID
resp . Payload [ 0 ] = header
2020-05-10 22:00:19 +00:00
}
s . subsLock . RLock ( )
subloop :
for sub := range s . subscribers {
2020-05-12 19:38:29 +00:00
if sub . overflown . Load ( ) {
continue
}
2020-05-13 14:13:33 +00:00
for i := range sub . feeds {
2022-10-17 10:31:24 +00:00
if rpcevent . Matches ( sub . feeds [ i ] , & resp ) {
2020-05-10 22:00:19 +00:00
if msg == nil {
2020-05-12 19:38:29 +00:00
b , err = json . Marshal ( resp )
2020-05-10 22:00:19 +00:00
if err != nil {
s . log . Error ( "failed to marshal notification" ,
zap . Error ( err ) ,
2022-12-13 09:44:54 +00:00
zap . Stringer ( "type" , resp . Event ) )
2020-05-10 22:00:19 +00:00
break subloop
}
msg , err = websocket . NewPreparedMessage ( websocket . TextMessage , b )
if err != nil {
s . log . Error ( "failed to prepare notification message" ,
zap . Error ( err ) ,
2022-12-13 09:44:54 +00:00
zap . Stringer ( "type" , resp . Event ) )
2020-05-10 22:00:19 +00:00
break subloop
}
}
2020-05-12 19:38:29 +00:00
select {
2023-02-15 07:07:47 +00:00
case sub . writer <- intEvent { msg , & resp } :
2020-05-12 19:38:29 +00:00
default :
sub . overflown . Store ( true )
// MissedEvent is to be delivered eventually.
go func ( sub * subscriber ) {
2023-02-15 07:07:47 +00:00
sub . writer <- intEvent { overflowMsg , & overflowEvent }
2020-05-12 19:38:29 +00:00
sub . overflown . Store ( false )
} ( sub )
}
2020-05-10 22:00:19 +00:00
// The message is sent only once per subscriber.
break
}
}
}
s . subsLock . RUnlock ( )
}
2022-11-18 07:40:28 +00:00
// It's important to do it with subsCounterLock held because no subscription routine
2020-05-10 22:00:19 +00:00
// should be running concurrently to this one. And even if one is to run
// after unlock, it'll see closed s.shutdown and won't subscribe.
2022-11-17 13:00:22 +00:00
s . subsCounterLock . Lock ( )
2020-05-10 22:00:19 +00:00
// There might be no subscription in reality, but it's not a problem as
// core.Blockchain allows unsubscribing non-subscribed channels.
s . chain . UnsubscribeFromBlocks ( s . blockCh )
s . chain . UnsubscribeFromTransactions ( s . transactionCh )
s . chain . UnsubscribeFromNotifications ( s . notificationCh )
s . chain . UnsubscribeFromExecutions ( s . executionCh )
2023-12-22 08:23:41 +00:00
s . chain . UnsubscribeFromHeadersOfAddedBlocks ( s . blockHeaderCh )
2021-05-28 11:55:06 +00:00
if s . chain . P2PSigExtensionsEnabled ( ) {
s . coreServer . UnsubscribeFromNotaryRequests ( s . notaryRequestCh )
}
2022-11-17 13:00:22 +00:00
s . subsCounterLock . Unlock ( )
2020-05-10 22:00:19 +00:00
drainloop :
for {
select {
case <- s . blockCh :
case <- s . executionCh :
case <- s . notificationCh :
case <- s . transactionCh :
2021-05-28 11:55:06 +00:00
case <- s . notaryRequestCh :
2023-12-22 08:23:41 +00:00
case <- s . blockHeaderCh :
2020-05-10 22:00:19 +00:00
default :
break drainloop
}
}
// It's not required closing these, but since they're drained already
2023-04-13 08:36:39 +00:00
// this is safe.
2020-05-10 22:00:19 +00:00
close ( s . blockCh )
close ( s . transactionCh )
close ( s . notificationCh )
close ( s . executionCh )
2021-05-28 11:55:06 +00:00
close ( s . notaryRequestCh )
2023-12-22 08:23:41 +00:00
close ( s . blockHeaderCh )
2023-04-13 08:36:39 +00:00
// notify Shutdown routine
close ( s . subEventsToExitCh )
2020-05-10 22:00:19 +00:00
}
2022-11-18 20:19:50 +00:00
func ( s * Server ) blockHeightFromParam ( param * params . Param ) ( uint32 , * neorpc . Error ) {
2019-11-26 10:13:17 +00:00
num , err := param . GetInt ( )
if err != nil {
2022-07-22 16:09:29 +00:00
return 0 , neorpc . ErrInvalidParams
2019-11-26 10:13:17 +00:00
}
2022-11-18 20:19:50 +00:00
if num < 0 || int64 ( num ) > int64 ( s . chain . BlockHeight ( ) ) {
2023-11-21 10:47:59 +00:00
return 0 , neorpc . WrapErrorWithData ( neorpc . ErrUnknownHeight , fmt . Sprintf ( "param at index %d should be greater than or equal to 0 and less than or equal to current block height, got: %d" , 0 , num ) )
2019-11-26 10:13:17 +00:00
}
2022-11-18 20:19:50 +00:00
return uint32 ( num ) , nil
2018-03-23 20:36:59 +00:00
}
2020-01-13 08:27:22 +00:00
2023-04-03 10:34:24 +00:00
func ( s * Server ) packResponse ( r * params . In , result any , respErr * neorpc . Error ) abstract {
2022-06-09 15:19:01 +00:00
resp := abstract {
2022-07-22 16:09:29 +00:00
Header : neorpc . Header {
2022-06-08 15:14:00 +00:00
JSONRPC : r . JSONRPC ,
ID : r . RawID ,
2020-01-14 12:02:38 +00:00
} ,
}
2020-04-28 19:56:19 +00:00
if respErr != nil {
2022-06-10 13:26:33 +00:00
resp . Error = respErr
2020-04-28 19:56:19 +00:00
} else {
2020-08-31 15:27:32 +00:00
resp . Result = result
2020-04-28 19:56:19 +00:00
}
return resp
}
2020-01-14 12:02:38 +00:00
2020-04-28 19:56:19 +00:00
// logRequestError is a request error logger.
2022-07-22 16:09:29 +00:00
func ( s * Server ) logRequestError ( r * params . Request , jsonErr * neorpc . Error ) {
2020-01-14 12:02:38 +00:00
logFields := [ ] zap . Field {
2022-06-23 14:41:28 +00:00
zap . Int64 ( "code" , jsonErr . Code ) ,
}
if len ( jsonErr . Data ) != 0 {
logFields = append ( logFields , zap . String ( "cause" , jsonErr . Data ) )
2020-01-14 12:02:38 +00:00
}
2020-10-26 17:22:20 +00:00
if r . In != nil {
logFields = append ( logFields , zap . String ( "method" , r . In . Method ) )
2022-07-07 14:41:01 +00:00
params := params . Params ( r . In . RawParams )
2021-10-28 11:10:18 +00:00
logFields = append ( logFields , zap . Any ( "params" , params ) )
2020-01-14 12:02:38 +00:00
}
2022-05-16 09:48:08 +00:00
logText := "Error encountered with rpc request"
switch jsonErr . Code {
2022-07-22 16:09:29 +00:00
case neorpc . InternalServerErrorCode :
2022-05-16 09:48:08 +00:00
s . log . Error ( logText , logFields ... )
default :
s . log . Info ( logText , logFields ... )
}
2020-01-14 12:02:38 +00:00
}
2020-04-28 19:56:19 +00:00
// writeHTTPErrorResponse writes an error response to the ResponseWriter.
2022-07-22 16:09:29 +00:00
func ( s * Server ) writeHTTPErrorResponse ( r * params . In , w http . ResponseWriter , jsonErr * neorpc . Error ) {
2020-08-31 15:27:32 +00:00
resp := s . packResponse ( r , nil , jsonErr )
2022-07-07 14:41:01 +00:00
s . writeHTTPServerResponse ( & params . Request { In : r } , w , resp )
2020-01-14 12:02:38 +00:00
}
2022-10-04 18:50:46 +00:00
func setCORSOriginHeaders ( h http . Header ) {
h . Set ( "Access-Control-Allow-Origin" , "*" )
h . Set ( "Access-Control-Allow-Headers" , "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With" )
}
2022-07-07 14:41:01 +00:00
func ( s * Server ) writeHTTPServerResponse ( r * params . Request , w http . ResponseWriter , resp abstractResult ) {
2020-04-28 19:56:19 +00:00
// Errors can happen in many places and we can only catch ALL of them here.
2022-07-22 16:09:29 +00:00
resp . RunForErrors ( func ( jsonErr * neorpc . Error ) {
2020-10-26 17:22:20 +00:00
s . logRequestError ( r , jsonErr )
} )
2023-08-01 12:46:01 +00:00
w . Header ( ) . Set ( "Content-Type" , "application/json; charset=utf-8" )
if s . config . EnableCORSWorkaround {
setCORSOriginHeaders ( w . Header ( ) )
}
2020-10-26 17:22:20 +00:00
if r . In != nil {
2022-06-09 15:19:01 +00:00
resp := resp . ( abstract )
2020-10-26 17:22:20 +00:00
if resp . Error != nil {
2022-06-10 13:26:33 +00:00
w . WriteHeader ( getHTTPCodeForError ( resp . Error ) )
2020-10-26 17:22:20 +00:00
}
2020-04-28 19:56:19 +00:00
}
2020-01-14 12:02:38 +00:00
encoder := json . NewEncoder ( w )
err := encoder . Encode ( resp )
if err != nil {
2020-10-26 17:22:20 +00:00
switch {
case r . In != nil :
s . log . Error ( "Error encountered while encoding response" ,
zap . String ( "err" , err . Error ( ) ) ,
zap . String ( "method" , r . In . Method ) )
case r . Batch != nil :
s . log . Error ( "Error encountered while encoding batch response" ,
zap . String ( "err" , err . Error ( ) ) )
}
2020-01-14 12:02:38 +00:00
}
}
2022-12-07 13:51:03 +00:00
// validateAddress verifies that the address is a correct Neo address
2020-01-13 08:27:22 +00:00
// see https://docs.neo.org/en-us/node/cli/2.9.4/api/validateaddress.html
2023-04-03 10:34:24 +00:00
func validateAddress ( addr any ) bool {
2020-01-13 08:27:22 +00:00
if addr , ok := addr . ( string ) ; ok {
_ , err := address . StringToUint160 ( addr )
2021-10-28 11:10:18 +00:00
return err == nil
2020-01-13 08:27:22 +00:00
}
2021-10-28 11:10:18 +00:00
return false
2020-01-13 08:27:22 +00:00
}
2022-03-21 20:36:19 +00:00
func escapeForLog ( in string ) string {
return strings . Map ( func ( c rune ) rune {
if ! strconv . IsGraphic ( c ) {
return - 1
}
return c
} , in )
}
2022-11-25 10:20:53 +00:00
// Addresses returns the list of addresses RPC server is listening to in the form of
// address:port.
func ( s * Server ) Addresses ( ) [ ] string {
res := make ( [ ] string , len ( s . http ) )
for i , srv := range s . http {
res [ i ] = srv . Addr
}
return res
}
2023-08-22 09:36:11 +00:00
func ( s * Server ) getRawNotaryPool ( _ params . Params ) ( any , * neorpc . Error ) {
if ! s . chain . P2PSigExtensionsEnabled ( ) {
return nil , neorpc . NewInternalServerError ( "P2PSignatureExtensions are disabled" )
}
nrp := s . coreServer . GetNotaryPool ( )
res := & result . RawNotaryPool { Hashes : make ( map [ util . Uint256 ] [ ] util . Uint256 ) }
nrp . IterateVerifiedTransactions ( func ( tx * transaction . Transaction , data any ) bool {
if data != nil {
d := data . ( * payload . P2PNotaryRequest )
mainHash := d . MainTransaction . Hash ( )
fallbackHash := d . FallbackTransaction . Hash ( )
res . Hashes [ mainHash ] = append ( res . Hashes [ mainHash ] , fallbackHash )
}
return true
} )
return res , nil
}
func ( s * Server ) getRawNotaryTransaction ( reqParams params . Params ) ( any , * neorpc . Error ) {
if ! s . chain . P2PSigExtensionsEnabled ( ) {
return nil , neorpc . NewInternalServerError ( "P2PSignatureExtensions are disabled" )
}
txHash , err := reqParams . Value ( 0 ) . GetUint256 ( )
if err != nil {
return nil , neorpc . ErrInvalidParams
}
nrp := s . coreServer . GetNotaryPool ( )
// Try to find fallback transaction.
tx , ok := nrp . TryGetValue ( txHash )
if ! ok {
// Try to find main transaction.
nrp . IterateVerifiedTransactions ( func ( t * transaction . Transaction , data any ) bool {
if data != nil && data . ( * payload . P2PNotaryRequest ) . MainTransaction . Hash ( ) . Equals ( txHash ) {
tx = data . ( * payload . P2PNotaryRequest ) . MainTransaction
return false
}
return true
} )
// The transaction was not found.
if tx == nil {
return nil , neorpc . ErrUnknownTransaction
}
}
if v , _ := reqParams . Value ( 1 ) . GetBoolean ( ) ; v {
return tx , nil
}
return tx . Bytes ( ) , nil
}