commit
834743ec88
131 changed files with 387 additions and 624 deletions
|
@ -41,18 +41,8 @@ jobs:
|
||||||
- run:
|
- run:
|
||||||
name: go-lint
|
name: go-lint
|
||||||
command: |
|
command: |
|
||||||
go get -u -v golang.org/x/lint/golint
|
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.40.0
|
||||||
golint -set_exit_status ./...
|
make lint
|
||||||
|
|
||||||
vet:
|
|
||||||
working_directory: /go/src/github.com/nspcc-dev/neo-go
|
|
||||||
executor: go1_16
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- gomod
|
|
||||||
- run:
|
|
||||||
name: go-vet
|
|
||||||
command: go vet ./...
|
|
||||||
|
|
||||||
test_1_14:
|
test_1_14:
|
||||||
working_directory: /go/src/github.com/nspcc-dev/neo-go
|
working_directory: /go/src/github.com/nspcc-dev/neo-go
|
||||||
|
@ -123,10 +113,6 @@ workflows:
|
||||||
version: 2
|
version: 2
|
||||||
workflow:
|
workflow:
|
||||||
jobs:
|
jobs:
|
||||||
- vet:
|
|
||||||
filters:
|
|
||||||
tags:
|
|
||||||
only: v/[0-9]+\.[0-9]+\.[0-9]+/
|
|
||||||
- lint:
|
- lint:
|
||||||
filters:
|
filters:
|
||||||
tags:
|
tags:
|
||||||
|
|
49
.github/workflows/run_tests.yml
vendored
49
.github/workflows/run_tests.yml
vendored
|
@ -16,53 +16,14 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
name: Lint
|
name: Lint
|
||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
- name: golangci-lint
|
||||||
- name: Set up Go
|
uses: golangci/golangci-lint-action@v2
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
with:
|
||||||
go-version: 1.16
|
version: latest
|
||||||
|
|
||||||
- name: Restore Go modules from cache
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: /home/runner/go/pkg/mod
|
|
||||||
key: deps-${{ hashFiles('go.sum') }}
|
|
||||||
|
|
||||||
- name: Update Go modules
|
|
||||||
run: go mod download -json
|
|
||||||
|
|
||||||
- name: Run linter
|
|
||||||
run: |
|
|
||||||
go get -u -v golang.org/x/lint/golint
|
|
||||||
make lint
|
|
||||||
|
|
||||||
vet:
|
|
||||||
name: Vet
|
|
||||||
runs-on: ubuntu-18.04
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Set up Go
|
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
|
||||||
go-version: 1.16
|
|
||||||
|
|
||||||
- name: Restore Go modules from cache
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: /home/runner/go/pkg/mod
|
|
||||||
key: deps-${{ hashFiles('go.sum') }}
|
|
||||||
|
|
||||||
- name: Update Go modules
|
|
||||||
run: go mod download -json
|
|
||||||
|
|
||||||
- name: Run vet
|
|
||||||
run: go vet ./...
|
|
||||||
|
|
||||||
test_cover:
|
test_cover:
|
||||||
name: Coverage
|
name: Coverage
|
||||||
|
@ -189,4 +150,4 @@ jobs:
|
||||||
run: go mod download -json
|
run: go mod download -json
|
||||||
|
|
||||||
- name: Build Docker image
|
- name: Build Docker image
|
||||||
run: make image
|
run: make image
|
||||||
|
|
59
.golangci.yml
Normal file
59
.golangci.yml
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
# This file contains all available configuration options
|
||||||
|
# with their default values.
|
||||||
|
|
||||||
|
# options for analysis running
|
||||||
|
run:
|
||||||
|
# timeout for analysis, e.g. 30s, 5m, default is 1m
|
||||||
|
timeout: 5m
|
||||||
|
|
||||||
|
# include test files or not, default is true
|
||||||
|
tests: true
|
||||||
|
|
||||||
|
# output configuration options
|
||||||
|
output:
|
||||||
|
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
|
||||||
|
format: tab
|
||||||
|
|
||||||
|
# all available settings of specific linters
|
||||||
|
linters-settings:
|
||||||
|
exhaustive:
|
||||||
|
# indicates that switch statements are to be considered exhaustive if a
|
||||||
|
# 'default' case is present, even if all enum members aren't listed in the
|
||||||
|
# switch
|
||||||
|
default-signifies-exhaustive: true
|
||||||
|
govet:
|
||||||
|
# report about shadowed variables
|
||||||
|
check-shadowing: false
|
||||||
|
|
||||||
|
linters:
|
||||||
|
enable:
|
||||||
|
# mandatory linters
|
||||||
|
- govet
|
||||||
|
- golint
|
||||||
|
|
||||||
|
# some default golangci-lint linters
|
||||||
|
- deadcode
|
||||||
|
- errcheck
|
||||||
|
- gosimple
|
||||||
|
- godot
|
||||||
|
- ineffassign
|
||||||
|
- staticcheck
|
||||||
|
- structcheck
|
||||||
|
- typecheck
|
||||||
|
- unused
|
||||||
|
- varcheck
|
||||||
|
|
||||||
|
# extra linters
|
||||||
|
# - exhaustive
|
||||||
|
- gofmt
|
||||||
|
- whitespace
|
||||||
|
- goimports
|
||||||
|
disable-all: true
|
||||||
|
fast: false
|
||||||
|
|
||||||
|
issues:
|
||||||
|
include:
|
||||||
|
- EXC0002 # should have a comment
|
||||||
|
- EXC0003 # test/Test ... consider calling this
|
||||||
|
- EXC0004 # govet
|
||||||
|
- EXC0005 # C-style breaks
|
2
Makefile
2
Makefile
|
@ -84,7 +84,7 @@ vet:
|
||||||
@go vet ./...
|
@go vet ./...
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
@go list ./... | xargs -L1 golint -set_exit_status
|
@golangci-lint run
|
||||||
|
|
||||||
fmt:
|
fmt:
|
||||||
@gofmt -l -w -s $$(find . -type f -name '*.go'| grep -v "/vendor/")
|
@gofmt -l -w -s $$(find . -type f -name '*.go'| grep -v "/vendor/")
|
||||||
|
|
|
@ -403,7 +403,8 @@ func TestComlileAndInvokeFunction(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
pk, err := keys.NewPrivateKey()
|
pk, err := keys.NewPrivateKey()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
acc.ConvertMultisig(2, keys.PublicKeys{acc.PrivateKey().PublicKey(), pk.PublicKey()})
|
err = acc.ConvertMultisig(2, keys.PublicKeys{acc.PrivateKey().PublicKey(), pk.PublicKey()})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
t.Run("cosigner is multisig account", func(t *testing.T) {
|
t.Run("cosigner is multisig account", func(t *testing.T) {
|
||||||
t.Run("missing in the wallet", func(t *testing.T) {
|
t.Run("missing in the wallet", func(t *testing.T) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ type Address struct {
|
||||||
Value util.Uint160
|
Value util.Uint160
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressFlag is a flag with type string
|
// AddressFlag is a flag with type string.
|
||||||
type AddressFlag struct {
|
type AddressFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Usage string
|
Usage string
|
||||||
|
@ -60,7 +60,7 @@ func (f AddressFlag) IsSet() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
// (for usage defaults)
|
// (for usage defaults).
|
||||||
func (f AddressFlag) String() string {
|
func (f AddressFlag) String() string {
|
||||||
var names []string
|
var names []string
|
||||||
eachName(f.Name, func(name string) {
|
eachName(f.Name, func(name string) {
|
||||||
|
@ -77,13 +77,13 @@ func getNameHelp(name string) string {
|
||||||
return fmt.Sprintf("--%s value", name)
|
return fmt.Sprintf("--%s value", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetName returns the name of the flag
|
// GetName returns the name of the flag.
|
||||||
func (f AddressFlag) GetName() string {
|
func (f AddressFlag) GetName() string {
|
||||||
return f.Name
|
return f.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
// Apply populates the flag given the flag set and environment
|
||||||
// Ignores errors
|
// Ignores errors.
|
||||||
func (f AddressFlag) Apply(set *flag.FlagSet) {
|
func (f AddressFlag) Apply(set *flag.FlagSet) {
|
||||||
eachName(f.Name, func(name string) {
|
eachName(f.Name, func(name string) {
|
||||||
set.Var(&f.Value, name, f.Usage)
|
set.Var(&f.Value, name, f.Usage)
|
||||||
|
|
|
@ -17,7 +17,7 @@ type ReadWriter struct {
|
||||||
io.Writer
|
io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadLine reads line from the input without trailing '\n'
|
// ReadLine reads line from the input without trailing '\n'.
|
||||||
func ReadLine(prompt string) (string, error) {
|
func ReadLine(prompt string) (string, error) {
|
||||||
trm := Terminal
|
trm := Terminal
|
||||||
if trm == nil {
|
if trm == nil {
|
||||||
|
@ -25,7 +25,7 @@ func ReadLine(prompt string) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer term.Restore(syscall.Stdin, s)
|
defer func() { _ = term.Restore(syscall.Stdin, s) }()
|
||||||
trm = term.NewTerminal(ReadWriter{
|
trm = term.NewTerminal(ReadWriter{
|
||||||
Reader: os.Stdin,
|
Reader: os.Stdin,
|
||||||
Writer: os.Stdout,
|
Writer: os.Stdout,
|
||||||
|
@ -50,7 +50,7 @@ func ReadPassword(prompt string) (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer term.Restore(syscall.Stdin, s)
|
defer func() { _ = term.Restore(syscall.Stdin, s) }()
|
||||||
trm = term.NewTerminal(ReadWriter{os.Stdin, os.Stdout}, prompt)
|
trm = term.NewTerminal(ReadWriter{os.Stdin, os.Stdout}, prompt)
|
||||||
}
|
}
|
||||||
return trm.ReadPassword(prompt)
|
return trm.ReadPassword(prompt)
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// nftOwnerAddr is the owner of NFT-ND HASHY token (../examples/nft-nd/nft.go)
|
// nftOwnerAddr is the owner of NFT-ND HASHY token (../examples/nft-nd/nft.go).
|
||||||
nftOwnerAddr = "NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB"
|
nftOwnerAddr = "NbrUYaZgyhSkNoRo9ugRyEMdUZxrhkNaWB"
|
||||||
nftOwnerWallet = "../examples/my_wallet.json"
|
nftOwnerWallet = "../examples/my_wallet.json"
|
||||||
nftOwnerPass = "qwerty"
|
nftOwnerPass = "qwerty"
|
||||||
|
|
|
@ -99,7 +99,6 @@ func TestNEP17Balance(t *testing.T) {
|
||||||
t.Run("Bad wallet", func(t *testing.T) {
|
t.Run("Bad wallet", func(t *testing.T) {
|
||||||
e.RunWithError(t, append(cmdbalance, "--wallet", "/dev/null")...)
|
e.RunWithError(t, append(cmdbalance, "--wallet", "/dev/null")...)
|
||||||
})
|
})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNEP17Transfer(t *testing.T) {
|
func TestNEP17Transfer(t *testing.T) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
)
|
)
|
||||||
|
|
||||||
// validUntilBlockIncrement is the number of extra blocks to add to an exported transaction
|
// validUntilBlockIncrement is the number of extra blocks to add to an exported transaction.
|
||||||
const validUntilBlockIncrement = 50
|
const validUntilBlockIncrement = 50
|
||||||
|
|
||||||
// InitAndSave creates incompletely signed transaction which can used
|
// InitAndSave creates incompletely signed transaction which can used
|
||||||
|
|
|
@ -62,9 +62,11 @@ func TestHandleLoggingParams(t *testing.T) {
|
||||||
func TestInitBCWithMetrics(t *testing.T) {
|
func TestInitBCWithMetrics(t *testing.T) {
|
||||||
d, err := ioutil.TempDir("./", "")
|
d, err := ioutil.TempDir("./", "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
os.Chdir(d)
|
err = os.Chdir(d)
|
||||||
|
require.NoError(t, err)
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
os.Chdir("..")
|
err = os.Chdir("..")
|
||||||
|
require.NoError(t, err)
|
||||||
os.RemoveAll(d)
|
os.RemoveAll(d)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -91,9 +93,11 @@ func TestDumpDB(t *testing.T) {
|
||||||
t.Run("too low chain", func(t *testing.T) {
|
t.Run("too low chain", func(t *testing.T) {
|
||||||
d, err := ioutil.TempDir("./", "")
|
d, err := ioutil.TempDir("./", "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
os.Chdir(d)
|
err = os.Chdir(d)
|
||||||
|
require.NoError(t, err)
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
os.Chdir("..")
|
err = os.Chdir("..")
|
||||||
|
require.NoError(t, err)
|
||||||
os.RemoveAll(d)
|
os.RemoveAll(d)
|
||||||
})
|
})
|
||||||
testDump := "file.acc"
|
testDump := "file.acc"
|
||||||
|
@ -112,9 +116,11 @@ func TestDumpDB(t *testing.T) {
|
||||||
t.Run("positive", func(t *testing.T) {
|
t.Run("positive", func(t *testing.T) {
|
||||||
d, err := ioutil.TempDir("./", "")
|
d, err := ioutil.TempDir("./", "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
os.Chdir(d)
|
err = os.Chdir(d)
|
||||||
|
require.NoError(t, err)
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
os.Chdir("..")
|
err = os.Chdir("..")
|
||||||
|
require.NoError(t, err)
|
||||||
os.RemoveAll(d)
|
os.RemoveAll(d)
|
||||||
})
|
})
|
||||||
testDump := "file.acc"
|
testDump := "file.acc"
|
||||||
|
@ -136,9 +142,11 @@ func TestRestoreDB(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
testDump := "file1.acc"
|
testDump := "file1.acc"
|
||||||
saveDump := "file2.acc"
|
saveDump := "file2.acc"
|
||||||
os.Chdir(d)
|
err = os.Chdir(d)
|
||||||
|
require.NoError(t, err)
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
os.Chdir("..")
|
err = os.Chdir("..")
|
||||||
|
require.NoError(t, err)
|
||||||
os.RemoveAll(d)
|
os.RemoveAll(d)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ var (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// smartContractTmpl is written to a file when used with `init` command.
|
// smartContractTmpl is written to a file when used with `init` command.
|
||||||
// %s is parsed to be the smartContractName
|
// %s is parsed to be the smartContractName.
|
||||||
smartContractTmpl = `package %s
|
smartContractTmpl = `package %s
|
||||||
|
|
||||||
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
import "github.com/nspcc-dev/neo-go/pkg/interop/runtime"
|
||||||
|
|
|
@ -13,9 +13,11 @@ import (
|
||||||
func TestInitSmartContract(t *testing.T) {
|
func TestInitSmartContract(t *testing.T) {
|
||||||
d, err := ioutil.TempDir("./", "")
|
d, err := ioutil.TempDir("./", "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
os.Chdir(d)
|
err = os.Chdir(d)
|
||||||
|
require.NoError(t, err)
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
os.Chdir("..")
|
err = os.Chdir("..")
|
||||||
|
require.NoError(t, err)
|
||||||
os.RemoveAll(d)
|
os.RemoveAll(d)
|
||||||
})
|
})
|
||||||
contractName := "testContract"
|
contractName := "testContract"
|
||||||
|
|
|
@ -156,7 +156,6 @@ func parseMultisigContract(script []byte) (int, keys.PublicKeys, bool) {
|
||||||
return 0, nil, false
|
return 0, nil, false
|
||||||
}
|
}
|
||||||
ret[i] = pub
|
ret[i] = pub
|
||||||
|
|
||||||
}
|
}
|
||||||
return nsigs, ret, true
|
return nsigs, ret, true
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,6 @@ func TestParseMultisigContract(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromHex(t *testing.T, s string) []byte {
|
func fromHex(t *testing.T, s string) []byte {
|
||||||
|
|
|
@ -226,7 +226,6 @@ func getNEP11Balance(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
fmt.Fprintf(ctx.App.Writer, format, formatArgs...)
|
fmt.Fprintf(ctx.App.Writer, format, formatArgs...)
|
||||||
fmt.Fprintf(ctx.App.Writer, "\tAmount : %s\n", amountStr)
|
fmt.Fprintf(ctx.App.Writer, "\tAmount : %s\n", amountStr)
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -243,7 +242,9 @@ func signAndSendNEP11Transfer(ctx *cli.Context, c *client.Client, acc *wallet.Ac
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if amount != nil {
|
if amount != nil {
|
||||||
from, err := address.StringToUint160(acc.Address)
|
var from util.Uint160
|
||||||
|
|
||||||
|
from, err = address.StringToUint160(acc.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("bad account address: %w", err), 1)
|
return cli.NewExitError(fmt.Errorf("bad account address: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -524,7 +524,7 @@ func removeAccount(ctx *cli.Context) error {
|
||||||
|
|
||||||
addr := ctx.Generic("address").(*flags.Address)
|
addr := ctx.Generic("address").(*flags.Address)
|
||||||
if !addr.IsSet {
|
if !addr.IsSet {
|
||||||
cli.NewExitError("valid account address must be provided", 1)
|
return cli.NewExitError("valid account address must be provided", 1)
|
||||||
}
|
}
|
||||||
acc := wall.GetAccount(addr.Uint160())
|
acc := wall.GetAccount(addr.Uint160())
|
||||||
if acc == nil {
|
if acc == nil {
|
||||||
|
|
|
@ -8,7 +8,6 @@ list for a new release.
|
||||||
These should run successfuly:
|
These should run successfuly:
|
||||||
* build
|
* build
|
||||||
* unit-tests
|
* unit-tests
|
||||||
* vet
|
|
||||||
* lint
|
* lint
|
||||||
* privnet with consensus nodes
|
* privnet with consensus nodes
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,6 @@ func NewDeployTx(bc blockchainer.Blockchainer, name string, sender util.Uint160,
|
||||||
o.ContractEvents = conf.Events
|
o.ContractEvents = conf.Events
|
||||||
o.ContractSupportedStandards = conf.SupportedStandards
|
o.ContractSupportedStandards = conf.SupportedStandards
|
||||||
o.SafeMethods = conf.SafeMethods
|
o.SafeMethods = conf.SafeMethods
|
||||||
|
|
||||||
}
|
}
|
||||||
m, err := compiler.CreateManifest(di, o)
|
m, err := compiler.CreateManifest(di, o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -302,10 +302,6 @@ func isInteropPath(s string) bool {
|
||||||
return strings.HasPrefix(s, interopPrefix)
|
return strings.HasPrefix(s, interopPrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isNativeHelpersPath(s string) bool {
|
|
||||||
return strings.HasPrefix(s, interopPrefix+"/native")
|
|
||||||
}
|
|
||||||
|
|
||||||
// canConvert returns true if type doesn't need to be converted on type assertion.
|
// canConvert returns true if type doesn't need to be converted on type assertion.
|
||||||
func canConvert(s string) bool {
|
func canConvert(s string) bool {
|
||||||
if len(s) != 0 && s[0] == '*' {
|
if len(s) != 0 && s[0] == '*' {
|
||||||
|
|
|
@ -339,7 +339,6 @@ func TestBooleanExprs(t *testing.T) {
|
||||||
t.Run(triple[i].s, getBoolExprTestFunc(triple[i].val, triple[i].s))
|
t.Run(triple[i].s, getBoolExprTestFunc(triple[i].val, triple[i].s))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShortCircuit(t *testing.T) {
|
func TestShortCircuit(t *testing.T) {
|
||||||
|
|
|
@ -132,7 +132,7 @@ const (
|
||||||
varArgument
|
varArgument
|
||||||
)
|
)
|
||||||
|
|
||||||
// newLabel creates a new label to jump to
|
// newLabel creates a new label to jump to.
|
||||||
func (c *codegen) newLabel() (l uint16) {
|
func (c *codegen) newLabel() (l uint16) {
|
||||||
li := len(c.l)
|
li := len(c.l)
|
||||||
if li > math.MaxUint16 {
|
if li > math.MaxUint16 {
|
||||||
|
@ -485,7 +485,6 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
switch n := node.(type) {
|
switch n := node.(type) {
|
||||||
|
|
||||||
// General declarations.
|
// General declarations.
|
||||||
// var (
|
// var (
|
||||||
// x = 2
|
// x = 2
|
||||||
|
@ -1511,7 +1510,7 @@ func (c *codegen) getLabelOffset(typ labelOffsetType, name string) uint16 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For `&&` and `||` it return an opcode which jumps only if result is known:
|
// For `&&` and `||` it return an opcode which jumps only if result is known:
|
||||||
// false && .. == false, true || .. = true
|
// false && .. == false, true || .. = true.
|
||||||
func getJumpForToken(tok token.Token, typ types.Type) (opcode.Opcode, bool) {
|
func getJumpForToken(tok token.Token, typ types.Type) (opcode.Opcode, bool) {
|
||||||
switch tok {
|
switch tok {
|
||||||
case token.GTR:
|
case token.GTR:
|
||||||
|
@ -1533,33 +1532,6 @@ func getJumpForToken(tok token.Token, typ types.Type) (opcode.Opcode, bool) {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// getByteArray returns byte array value from constant expr.
|
|
||||||
// Only literals are supported.
|
|
||||||
func (c *codegen) getByteArray(expr ast.Expr) []byte {
|
|
||||||
switch t := expr.(type) {
|
|
||||||
case *ast.CompositeLit:
|
|
||||||
if !isByteSlice(c.typeOf(t.Type)) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
buf := make([]byte, len(t.Elts))
|
|
||||||
for i := 0; i < len(t.Elts); i++ {
|
|
||||||
t := c.typeAndValueOf(t.Elts[i])
|
|
||||||
val, _ := constant.Int64Val(t.Value)
|
|
||||||
buf[i] = byte(val)
|
|
||||||
}
|
|
||||||
return buf
|
|
||||||
case *ast.CallExpr:
|
|
||||||
if tv := c.typeAndValueOf(t.Args[0]); tv.Value != nil {
|
|
||||||
val := constant.StringVal(tv.Value)
|
|
||||||
return []byte(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *codegen) convertSyscall(f *funcScope, expr *ast.CallExpr) {
|
func (c *codegen) convertSyscall(f *funcScope, expr *ast.CallExpr) {
|
||||||
for _, arg := range expr.Args[1:] {
|
for _, arg := range expr.Args[1:] {
|
||||||
ast.Walk(c, arg)
|
ast.Walk(c, arg)
|
||||||
|
|
|
@ -345,7 +345,7 @@ func (d *DebugParam) UnmarshalJSON(data []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToManifestParameter converts DebugParam to manifest.Parameter
|
// ToManifestParameter converts DebugParam to manifest.Parameter.
|
||||||
func (d *DebugParam) ToManifestParameter() manifest.Parameter {
|
func (d *DebugParam) ToManifestParameter() manifest.Parameter {
|
||||||
return manifest.Parameter{
|
return manifest.Parameter{
|
||||||
Name: d.Name,
|
Name: d.Name,
|
||||||
|
@ -353,7 +353,7 @@ func (d *DebugParam) ToManifestParameter() manifest.Parameter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToManifestMethod converts MethodDebugInfo to manifest.Method
|
// ToManifestMethod converts MethodDebugInfo to manifest.Method.
|
||||||
func (m *MethodDebugInfo) ToManifestMethod() manifest.Method {
|
func (m *MethodDebugInfo) ToManifestMethod() manifest.Method {
|
||||||
var (
|
var (
|
||||||
result manifest.Method
|
result manifest.Method
|
||||||
|
|
|
@ -10,11 +10,11 @@ import (
|
||||||
|
|
||||||
// inlineCall inlines call of n for function represented by f.
|
// inlineCall inlines call of n for function represented by f.
|
||||||
// Call `f(a,b)` for definition `func f(x,y int)` is translated to block:
|
// Call `f(a,b)` for definition `func f(x,y int)` is translated to block:
|
||||||
// {
|
// {
|
||||||
// x := a
|
// x := a
|
||||||
// y := b
|
// y := b
|
||||||
// <inline body of f directly>
|
// <inline body of f directly>
|
||||||
// }
|
// }
|
||||||
func (c *codegen) inlineCall(f *funcScope, n *ast.CallExpr) {
|
func (c *codegen) inlineCall(f *funcScope, n *ast.CallExpr) {
|
||||||
labelSz := len(c.labelList)
|
labelSz := len(c.labelList)
|
||||||
offSz := len(c.inlineLabelOffsets)
|
offSz := len(c.inlineLabelOffsets)
|
||||||
|
|
|
@ -33,26 +33,17 @@ import (
|
||||||
|
|
||||||
func TestContractHashes(t *testing.T) {
|
func TestContractHashes(t *testing.T) {
|
||||||
cs := native.NewContracts(true, map[string][]uint32{})
|
cs := native.NewContracts(true, map[string][]uint32{})
|
||||||
require.Equal(t, []byte(neo.Hash), cs.NEO.Hash.BytesBE())
|
require.Equalf(t, []byte(neo.Hash), cs.NEO.Hash.BytesBE(), "%q", string(cs.NEO.Hash.BytesBE()))
|
||||||
require.Equal(t, []byte(gas.Hash), cs.GAS.Hash.BytesBE())
|
require.Equalf(t, []byte(gas.Hash), cs.GAS.Hash.BytesBE(), "%q", string(cs.GAS.Hash.BytesBE()))
|
||||||
require.Equal(t, []byte(oracle.Hash), cs.Oracle.Hash.BytesBE())
|
require.Equalf(t, []byte(oracle.Hash), cs.Oracle.Hash.BytesBE(), "%q", string(cs.Oracle.Hash.BytesBE()))
|
||||||
require.Equal(t, []byte(roles.Hash), cs.Designate.Hash.BytesBE())
|
require.Equalf(t, []byte(roles.Hash), cs.Designate.Hash.BytesBE(), "%q", string(cs.Designate.Hash.BytesBE()))
|
||||||
require.Equal(t, []byte(policy.Hash), cs.Policy.Hash.BytesBE())
|
require.Equalf(t, []byte(policy.Hash), cs.Policy.Hash.BytesBE(), "%q", string(cs.Policy.Hash.BytesBE()))
|
||||||
require.Equal(t, []byte(nameservice.Hash), cs.NameService.Hash.BytesBE())
|
require.Equalf(t, []byte(nameservice.Hash), cs.NameService.Hash.BytesBE(), "%q", string(cs.NameService.Hash.BytesBE()))
|
||||||
require.Equal(t, []byte(ledger.Hash), cs.Ledger.Hash.BytesBE())
|
require.Equalf(t, []byte(ledger.Hash), cs.Ledger.Hash.BytesBE(), "%q", string(cs.Ledger.Hash.BytesBE()))
|
||||||
require.Equal(t, []byte(management.Hash), cs.Management.Hash.BytesBE())
|
require.Equalf(t, []byte(management.Hash), cs.Management.Hash.BytesBE(), "%q", string(cs.Management.Hash.BytesBE()))
|
||||||
require.Equal(t, []byte(notary.Hash), cs.Notary.Hash.BytesBE())
|
require.Equalf(t, []byte(notary.Hash), cs.Notary.Hash.BytesBE(), "%q", string(cs.Notary.Hash.BytesBE()))
|
||||||
require.Equal(t, []byte(crypto.Hash), cs.Crypto.Hash.BytesBE())
|
require.Equalf(t, []byte(crypto.Hash), cs.Crypto.Hash.BytesBE(), "%q", string(cs.Crypto.Hash.BytesBE()))
|
||||||
require.Equal(t, []byte(std.Hash), cs.Std.Hash.BytesBE())
|
require.Equalf(t, []byte(std.Hash), cs.Std.Hash.BytesBE(), "%q", string(cs.Std.Hash.BytesBE()))
|
||||||
}
|
|
||||||
|
|
||||||
// testPrintHash is a helper for updating contract hashes.
|
|
||||||
func testPrintHash(u util.Uint160) {
|
|
||||||
fmt.Print(`"`)
|
|
||||||
for _, b := range u.BytesBE() {
|
|
||||||
fmt.Printf("\\x%02x", b)
|
|
||||||
}
|
|
||||||
fmt.Println(`"`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContractParameterTypes(t *testing.T) {
|
func TestContractParameterTypes(t *testing.T) {
|
||||||
|
@ -255,12 +246,12 @@ func getMethod(t *testing.T, ctr interop.ContractMD, name string, params []strin
|
||||||
name = name[:4]
|
name = name[:4]
|
||||||
case strings.HasPrefix(name, "memorySearch"):
|
case strings.HasPrefix(name, "memorySearch"):
|
||||||
if strings.HasSuffix(name, "LastIndex") {
|
if strings.HasSuffix(name, "LastIndex") {
|
||||||
paramLen += 1 // true should be appended inside of an interop
|
paramLen++ // true should be appended inside of an interop
|
||||||
}
|
}
|
||||||
name = "memorySearch"
|
name = "memorySearch"
|
||||||
case strings.HasPrefix(name, "stringSplit"):
|
case strings.HasPrefix(name, "stringSplit"):
|
||||||
if strings.HasSuffix(name, "NonEmpty") {
|
if strings.HasSuffix(name, "NonEmpty") {
|
||||||
paramLen += 1 // true should be appended inside of an interop
|
paramLen++ // true should be appended inside of an interop
|
||||||
}
|
}
|
||||||
name = "stringSplit"
|
name = "stringSplit"
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
|
|
||||||
type varScope struct {
|
type varScope struct {
|
||||||
localsCnt int
|
localsCnt int
|
||||||
argCnt int
|
|
||||||
arguments map[string]int
|
arguments map[string]int
|
||||||
locals []map[string]varInfo
|
locals []map[string]varInfo
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,6 @@ func newStoragePlugin() *storagePlugin {
|
||||||
s.interops[interopnames.ToID([]byte(interopnames.SystemRuntimeNotify))] = s.Notify
|
s.interops[interopnames.ToID([]byte(interopnames.SystemRuntimeNotify))] = s.Notify
|
||||||
s.interops[interopnames.ToID([]byte(interopnames.SystemRuntimeGetTime))] = s.GetTime
|
s.interops[interopnames.ToID([]byte(interopnames.SystemRuntimeGetTime))] = s.GetTime
|
||||||
return s
|
return s
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *storagePlugin) syscallHandler(v *vm.VM, id uint32) error {
|
func (s *storagePlugin) syscallHandler(v *vm.VM, id uint32) error {
|
||||||
|
|
|
@ -11,7 +11,7 @@ type commit struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// signatureSize is an rfc6989 signature size in bytes
|
// signatureSize is an rfc6989 signature size in bytes
|
||||||
// without leading byte (0x04, uncompressed)
|
// without leading byte (0x04, uncompressed).
|
||||||
const signatureSize = 64
|
const signatureSize = 64
|
||||||
|
|
||||||
var _ payload.Commit = (*commit)(nil)
|
var _ payload.Commit = (*commit)(nil)
|
||||||
|
|
|
@ -309,7 +309,6 @@ events:
|
||||||
s.handleChainBlock(b)
|
s.handleChainBlock(b)
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
close(s.finished)
|
close(s.finished)
|
||||||
}
|
}
|
||||||
|
@ -373,7 +372,12 @@ func (s *service) payloadFromExtensible(ep *npayload.Extensible) *Payload {
|
||||||
func (s *service) OnPayload(cp *npayload.Extensible) {
|
func (s *service) OnPayload(cp *npayload.Extensible) {
|
||||||
log := s.log.With(zap.Stringer("hash", cp.Hash()))
|
log := s.log.With(zap.Stringer("hash", cp.Hash()))
|
||||||
p := s.payloadFromExtensible(cp)
|
p := s.payloadFromExtensible(cp)
|
||||||
p.decodeData()
|
// decode payload data into message
|
||||||
|
if err := p.decodeData(); err != nil {
|
||||||
|
log.Info("can't decode payload data", zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if !s.validatePayload(p) {
|
if !s.validatePayload(p) {
|
||||||
log.Info("can't validate payload")
|
log.Info("can't validate payload")
|
||||||
return
|
return
|
||||||
|
@ -384,14 +388,6 @@ func (s *service) OnPayload(cp *npayload.Extensible) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode payload data into message
|
|
||||||
if p.message.payload == nil {
|
|
||||||
if err := p.decodeData(); err != nil {
|
|
||||||
log.Info("can't decode payload data")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s.messages <- *p
|
s.messages <- *p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,9 @@ func (p *Payload) Hash() util.Uint256 {
|
||||||
// DecodeBinary implements io.Serializable interface.
|
// DecodeBinary implements io.Serializable interface.
|
||||||
func (p *Payload) DecodeBinary(r *io.BinReader) {
|
func (p *Payload) DecodeBinary(r *io.BinReader) {
|
||||||
p.Extensible.DecodeBinary(r)
|
p.Extensible.DecodeBinary(r)
|
||||||
p.decodeData()
|
if r.Err == nil {
|
||||||
|
r.Err = p.decodeData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeBinary implements io.Serializable interface.
|
// EncodeBinary implements io.Serializable interface.
|
||||||
|
@ -231,7 +233,7 @@ func (p *Payload) encodeData() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode data of payload into it's message
|
// decode data of payload into its message.
|
||||||
func (p *Payload) decodeData() error {
|
func (p *Payload) decodeData() error {
|
||||||
br := io.NewBinReaderFromBuf(p.Extensible.Data)
|
br := io.NewBinReaderFromBuf(p.Extensible.Data)
|
||||||
p.message.DecodeBinary(br)
|
p.message.DecodeBinary(br)
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft/payload"
|
||||||
"github.com/nspcc-dev/neo-go/internal/testchain"
|
"github.com/nspcc-dev/neo-go/internal/testchain"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -157,16 +156,3 @@ func TestRecoveryMessage_Decode(t *testing.T) {
|
||||||
require.Equal(t, gio.EOF, buf.Err)
|
require.Equal(t, gio.EOF, buf.Err)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func getKeys(t *testing.T, n int) []*privateKey {
|
|
||||||
privs := make([]*privateKey, 0, n)
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
priv, err := keys.NewPrivateKey()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotNil(t, priv)
|
|
||||||
|
|
||||||
privs = append(privs, &privateKey{PrivateKey: priv})
|
|
||||||
}
|
|
||||||
|
|
||||||
return privs
|
|
||||||
}
|
|
||||||
|
|
|
@ -215,7 +215,7 @@ func (b *Block) UnmarshalJSON(data []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExpectedBlockSize returns expected block size which should be equal to io.GetVarSize(b)
|
// GetExpectedBlockSize returns expected block size which should be equal to io.GetVarSize(b).
|
||||||
func (b *Block) GetExpectedBlockSize() int {
|
func (b *Block) GetExpectedBlockSize() int {
|
||||||
var transactionsSize int
|
var transactionsSize int
|
||||||
for _, tx := range b.Transactions {
|
for _, tx := range b.Transactions {
|
||||||
|
|
|
@ -239,7 +239,6 @@ func TestBlockEncodeDecode(t *testing.T) {
|
||||||
|
|
||||||
func TestGetExpectedBlockSize(t *testing.T) {
|
func TestGetExpectedBlockSize(t *testing.T) {
|
||||||
check := func(t *testing.T, stateRootEnabled bool) {
|
check := func(t *testing.T, stateRootEnabled bool) {
|
||||||
|
|
||||||
t.Run("without transactions", func(t *testing.T) {
|
t.Run("without transactions", func(t *testing.T) {
|
||||||
b := newDumbBlock()
|
b := newDumbBlock()
|
||||||
b.StateRootEnabled = stateRootEnabled
|
b.StateRootEnabled = stateRootEnabled
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Header holds the base info of a block
|
// Header holds the base info of a block.
|
||||||
type Header struct {
|
type Header struct {
|
||||||
// Version of the block.
|
// Version of the block.
|
||||||
Version uint32
|
Version uint32
|
||||||
|
@ -84,7 +84,7 @@ func (b *Header) DecodeBinary(br *io.BinReader) {
|
||||||
b.Script.DecodeBinary(br)
|
b.Script.DecodeBinary(br)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeBinary implements Serializable interface
|
// EncodeBinary implements Serializable interface.
|
||||||
func (b *Header) EncodeBinary(bw *io.BinWriter) {
|
func (b *Header) EncodeBinary(bw *io.BinWriter) {
|
||||||
b.encodeHashableFields(bw)
|
b.encodeHashableFields(bw)
|
||||||
bw.WriteVarUint(1)
|
bw.WriteVarUint(1)
|
||||||
|
|
|
@ -1600,7 +1600,6 @@ func (bc *Blockchain) IsTxStillRelevant(t *transaction.Transaction, txpool *memp
|
||||||
return bc.verifyTxWitnesses(t, nil, isPartialTx) == nil
|
return bc.verifyTxWitnesses(t, nil, isPartialTx) == nil
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyTx verifies whether transaction is bonafide or not relative to the
|
// VerifyTx verifies whether transaction is bonafide or not relative to the
|
||||||
|
|
|
@ -238,6 +238,7 @@ func TestGetBlock(t *testing.T) {
|
||||||
t.Run("non-empty block", func(t *testing.T) {
|
t.Run("non-empty block", func(t *testing.T) {
|
||||||
tx, err := testchain.NewTransferFromOwner(bc, bc.contracts.NEO.Hash,
|
tx, err := testchain.NewTransferFromOwner(bc, bc.contracts.NEO.Hash,
|
||||||
random.Uint160(), 1, 1, 1000)
|
random.Uint160(), 1, 1, 1000)
|
||||||
|
require.NoError(t, err)
|
||||||
b := bc.newBlock(tx)
|
b := bc.newBlock(tx)
|
||||||
require.NoError(t, bc.AddHeaders(&b.Header))
|
require.NoError(t, bc.AddHeaders(&b.Header))
|
||||||
|
|
||||||
|
@ -1024,7 +1025,7 @@ func TestVerifyTx(t *testing.T) {
|
||||||
nativeprices.NotaryVerificationPrice*bc.GetBaseExecFee() // Notary witness verification price
|
nativeprices.NotaryVerificationPrice*bc.GetBaseExecFee() // Notary witness verification price
|
||||||
tx.Scripts = []transaction.Witness{
|
tx.Scripts = []transaction.Witness{
|
||||||
{
|
{
|
||||||
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...),
|
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...),
|
||||||
VerificationScript: []byte{},
|
VerificationScript: []byte{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1051,7 +1052,7 @@ func TestVerifyTx(t *testing.T) {
|
||||||
tx.NetworkFee-- // to check that NetworkFee was set correctly in getPartiallyFilledTx
|
tx.NetworkFee-- // to check that NetworkFee was set correctly in getPartiallyFilledTx
|
||||||
tx.Scripts = []transaction.Witness{
|
tx.Scripts = []transaction.Witness{
|
||||||
{
|
{
|
||||||
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...),
|
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...),
|
||||||
VerificationScript: []byte{},
|
VerificationScript: []byte{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1528,7 +1529,6 @@ func testDumpAndRestore(t *testing.T, dumpF, restoreF func(c *config.Config)) {
|
||||||
require.Equal(t, bc.BlockHeight()-1, lastIndex)
|
require.Equal(t, bc.BlockHeight()-1, lastIndex)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDumpAndRestore(t *testing.T) {
|
func TestDumpAndRestore(t *testing.T) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HasTransaction errors
|
// HasTransaction errors.
|
||||||
var (
|
var (
|
||||||
// ErrAlreadyExists is returned when transaction exists in dao.
|
// ErrAlreadyExists is returned when transaction exists in dao.
|
||||||
ErrAlreadyExists = errors.New("transaction already exists")
|
ErrAlreadyExists = errors.New("transaction already exists")
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
// ECDSAVerifyPrice is a gas price of a single verification.
|
// ECDSAVerifyPrice is a gas price of a single verification.
|
||||||
const ECDSAVerifyPrice = 1 << 15
|
const ECDSAVerifyPrice = 1 << 15
|
||||||
|
|
||||||
// Calculate returns network fee for transaction
|
// Calculate returns network fee for transaction.
|
||||||
func Calculate(base int64, script []byte) (int64, int) {
|
func Calculate(base int64, script []byte) (int64, int) {
|
||||||
var (
|
var (
|
||||||
netFee int64
|
netFee int64
|
||||||
|
@ -25,9 +25,9 @@ func Calculate(base int64, script []byte) (int64, int) {
|
||||||
size += io.GetVarSize(sizeInv) + sizeInv + io.GetVarSize(script)
|
size += io.GetVarSize(sizeInv) + sizeInv + io.GetVarSize(script)
|
||||||
netFee += calculateMultisig(base, m) + calculateMultisig(base, n)
|
netFee += calculateMultisig(base, m) + calculateMultisig(base, n)
|
||||||
netFee += base * ECDSAVerifyPrice * int64(n)
|
netFee += base * ECDSAVerifyPrice * int64(n)
|
||||||
} else {
|
} /*else {
|
||||||
// We can support more contract types in the future.
|
// We can support more contract types in the future.
|
||||||
}
|
}*/
|
||||||
return netFee, size
|
return netFee, size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/internal/testchain"
|
"github.com/nspcc-dev/neo-go/internal/testchain"
|
||||||
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/compiler"
|
"github.com/nspcc-dev/neo-go/pkg/compiler"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
|
@ -28,7 +27,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
|
@ -46,7 +44,7 @@ import (
|
||||||
"go.uber.org/zap/zaptest"
|
"go.uber.org/zap/zaptest"
|
||||||
)
|
)
|
||||||
|
|
||||||
// multisig address which possess all NEO
|
// multisig address which possess all NEO.
|
||||||
var neoOwner = testchain.MultisigScriptHash()
|
var neoOwner = testchain.MultisigScriptHash()
|
||||||
|
|
||||||
// newTestChain should be called before newBlock invocation to properly setup
|
// newTestChain should be called before newBlock invocation to properly setup
|
||||||
|
@ -180,51 +178,6 @@ func TestBug1728(t *testing.T) {
|
||||||
require.Equal(t, aer.VMState, vm.HaltState)
|
require.Equal(t, aer.VMState, vm.HaltState)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDecodedBlock(t *testing.T, i int) *block.Block {
|
|
||||||
data, err := getBlockData(i)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
b, err := hex.DecodeString(data["raw"].(string))
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
block := block.New(false)
|
|
||||||
require.NoError(t, testserdes.DecodeBinary(b, block))
|
|
||||||
|
|
||||||
return block
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBlockData(i int) (map[string]interface{}, error) {
|
|
||||||
b, err := ioutil.ReadFile(fmt.Sprintf("test_data/block_%d.json", i))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var data map[string]interface{}
|
|
||||||
if err := json.Unmarshal(b, &data); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return data, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDumbBlock() *block.Block {
|
|
||||||
return &block.Block{
|
|
||||||
Header: block.Header{
|
|
||||||
Version: 0,
|
|
||||||
PrevHash: hash.Sha256([]byte("a")),
|
|
||||||
MerkleRoot: hash.Sha256([]byte("b")),
|
|
||||||
Timestamp: 100500,
|
|
||||||
Index: 1,
|
|
||||||
NextConsensus: hash.Hash160([]byte("a")),
|
|
||||||
Script: transaction.Witness{
|
|
||||||
VerificationScript: []byte{0x51}, // PUSH1
|
|
||||||
InvocationScript: []byte{0x61}, // NOP
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Transactions: []*transaction.Transaction{
|
|
||||||
transaction.New([]byte{byte(opcode.PUSH1)}, 0),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function generates "../rpc/testdata/testblocks.acc" file which contains data
|
// This function generates "../rpc/testdata/testblocks.acc" file which contains data
|
||||||
// for RPC unit tests. It also is a nice integration test.
|
// for RPC unit tests. It also is a nice integration test.
|
||||||
// To generate new "../rpc/testdata/testblocks.acc", follow the steps:
|
// To generate new "../rpc/testdata/testblocks.acc", follow the steps:
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/internal/random"
|
"github.com/nspcc-dev/neo-go/internal/random"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/contract"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop/contract"
|
||||||
|
@ -451,27 +450,6 @@ func createVM(t *testing.T) (*vm.VM, *interop.Context, *Blockchain) {
|
||||||
return v, context, chain
|
return v, context, chain
|
||||||
}
|
}
|
||||||
|
|
||||||
func createVMAndPushBlock(t *testing.T) (*vm.VM, *block.Block, *interop.Context, *Blockchain) {
|
|
||||||
v, block, context, chain := createVMAndBlock(t)
|
|
||||||
v.Estack().PushVal(stackitem.NewInterop(block))
|
|
||||||
return v, block, context, chain
|
|
||||||
}
|
|
||||||
|
|
||||||
func createVMAndBlock(t *testing.T) (*vm.VM, *block.Block, *interop.Context, *Blockchain) {
|
|
||||||
block := newDumbBlock()
|
|
||||||
chain := newTestChain(t)
|
|
||||||
d := dao.NewSimple(storage.NewMemoryStore(), chain.GetConfig().StateRootInHeader)
|
|
||||||
context := chain.newInteropContext(trigger.Application, d, block, nil)
|
|
||||||
v := context.SpawnVM()
|
|
||||||
return v, block, context, chain
|
|
||||||
}
|
|
||||||
|
|
||||||
func createVMAndPushTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) {
|
|
||||||
v, tx, context, chain := createVMAndTX(t)
|
|
||||||
v.Estack().PushVal(stackitem.NewInterop(tx))
|
|
||||||
return v, tx, context, chain
|
|
||||||
}
|
|
||||||
|
|
||||||
func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.Context, *Blockchain) {
|
func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.Context, *Blockchain) {
|
||||||
script := []byte("testscript")
|
script := []byte("testscript")
|
||||||
m := manifest.NewManifest("Test")
|
m := manifest.NewManifest("Test")
|
||||||
|
|
|
@ -47,7 +47,7 @@ type item struct {
|
||||||
type items []item
|
type items []item
|
||||||
|
|
||||||
// utilityBalanceAndFees stores sender's balance and overall fees of
|
// utilityBalanceAndFees stores sender's balance and overall fees of
|
||||||
// sender's transactions which are currently in mempool
|
// sender's transactions which are currently in mempool.
|
||||||
type utilityBalanceAndFees struct {
|
type utilityBalanceAndFees struct {
|
||||||
balance *big.Int
|
balance *big.Int
|
||||||
feeSum *big.Int
|
feeSum *big.Int
|
||||||
|
@ -158,7 +158,7 @@ func (mp *Pool) HasConflicts(t *transaction.Transaction, fee Feer) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// tryAddSendersFee tries to add system fee and network fee to the total sender`s fee in mempool
|
// tryAddSendersFee tries to add system fee and network fee to the total sender`s fee in mempool
|
||||||
// and returns false if both balance check is required and sender has not enough GAS to pay
|
// and returns false if both balance check is required and sender has not enough GAS to pay.
|
||||||
func (mp *Pool) tryAddSendersFee(tx *transaction.Transaction, feer Feer, needCheck bool) bool {
|
func (mp *Pool) tryAddSendersFee(tx *transaction.Transaction, feer Feer, needCheck bool) bool {
|
||||||
payer := tx.Signers[mp.payerIndex].Account
|
payer := tx.Signers[mp.payerIndex].Account
|
||||||
senderFee, ok := mp.fees[payer]
|
senderFee, ok := mp.fees[payer]
|
||||||
|
@ -304,7 +304,7 @@ func (mp *Pool) Remove(hash util.Uint256, feer Feer) {
|
||||||
mp.lock.Unlock()
|
mp.lock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// removeInternal is an internal unlocked representation of Remove
|
// removeInternal is an internal unlocked representation of Remove.
|
||||||
func (mp *Pool) removeInternal(hash util.Uint256, feer Feer) {
|
func (mp *Pool) removeInternal(hash util.Uint256, feer Feer) {
|
||||||
if tx, ok := mp.verifiedMap[hash]; ok {
|
if tx, ok := mp.verifiedMap[hash]; ok {
|
||||||
var num int
|
var num int
|
||||||
|
|
|
@ -298,10 +298,7 @@ func TestMemPoolFees(t *testing.T) {
|
||||||
|
|
||||||
// check whether sender's fee updates correctly
|
// check whether sender's fee updates correctly
|
||||||
mp.RemoveStale(func(t *transaction.Transaction) bool {
|
mp.RemoveStale(func(t *transaction.Transaction) bool {
|
||||||
if t == tx2 {
|
return t == tx2
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}, fs)
|
}, fs)
|
||||||
require.Equal(t, 1, len(mp.fees))
|
require.Equal(t, 1, len(mp.fees))
|
||||||
require.Equal(t, utilityBalanceAndFees{
|
require.Equal(t, utilityBalanceAndFees{
|
||||||
|
@ -311,10 +308,7 @@ func TestMemPoolFees(t *testing.T) {
|
||||||
|
|
||||||
// there should be nothing left
|
// there should be nothing left
|
||||||
mp.RemoveStale(func(t *transaction.Transaction) bool {
|
mp.RemoveStale(func(t *transaction.Transaction) bool {
|
||||||
if t == tx3 {
|
return t == tx3
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}, fs)
|
}, fs)
|
||||||
require.Equal(t, 0, len(mp.fees))
|
require.Equal(t, 0, len(mp.fees))
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,10 +75,7 @@ func TestSubscriptions(t *testing.T) {
|
||||||
|
|
||||||
// remove stale
|
// remove stale
|
||||||
mp.RemoveStale(func(tx *transaction.Transaction) bool {
|
mp.RemoveStale(func(tx *transaction.Transaction) bool {
|
||||||
if tx.Hash().Equals(txs[2].Hash()) {
|
return !tx.Hash().Equals(txs[2].Hash())
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}, fs)
|
}, fs)
|
||||||
require.Eventually(t, func() bool { return len(subChan1) == 1 && len(subChan2) == 1 }, time.Second, time.Millisecond*100)
|
require.Eventually(t, func() bool { return len(subChan1) == 1 && len(subChan2) == 1 }, time.Second, time.Millisecond*100)
|
||||||
event1 = <-subChan1
|
event1 = <-subChan1
|
||||||
|
|
|
@ -208,7 +208,6 @@ func (t *Trie) newSubTrieMany(prefix []byte, kv []keyValue, value []byte) (Node,
|
||||||
if len(kv[0].value) == 0 {
|
if len(kv[0].value) == 0 {
|
||||||
if len(kv) == 1 {
|
if len(kv) == 1 {
|
||||||
return new(HashNode), 1, nil
|
return new(HashNode), 1, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
node, n, err := t.newSubTrieMany(prefix, kv[1:], nil)
|
node, n, err := t.newSubTrieMany(prefix, kv[1:], nil)
|
||||||
return node, n + 1, err
|
return node, n + 1, err
|
||||||
|
|
|
@ -277,9 +277,11 @@ func TestTrie_PutBatch(t *testing.T) {
|
||||||
testPut(t, ps, tr1, tr2)
|
testPut(t, ps, tr1, tr2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ = printNode
|
||||||
|
|
||||||
// This function is unused, but is helpful for debugging
|
// This function is unused, but is helpful for debugging
|
||||||
// as it provides more readable Trie representation compared to
|
// as it provides more readable Trie representation compared to
|
||||||
// `spew.Dump()`
|
// `spew.Dump()`.
|
||||||
func printNode(prefix string, n Node) {
|
func printNode(prefix string, n Node) {
|
||||||
switch tn := n.(type) {
|
switch tn := n.(type) {
|
||||||
case *HashNode:
|
case *HashNode:
|
||||||
|
|
|
@ -25,14 +25,7 @@ type Ledger struct {
|
||||||
interop.ContractMD
|
interop.ContractMD
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const ledgerContractID = -4
|
||||||
ledgerContractID = -4
|
|
||||||
|
|
||||||
prefixBlockHash = 9
|
|
||||||
prefixCurrentBlock = 12
|
|
||||||
prefixBlock = 5
|
|
||||||
prefixTransaction = 11
|
|
||||||
)
|
|
||||||
|
|
||||||
// newLedger creates new Ledger native contract.
|
// newLedger creates new Ledger native contract.
|
||||||
func newLedger() *Ledger {
|
func newLedger() *Ledger {
|
||||||
|
@ -199,7 +192,7 @@ func getTransactionAndHeight(cd *dao.Cached, item stackitem.Item) (*transaction.
|
||||||
return cd.GetTransaction(hash)
|
return cd.GetTransaction(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockToStackItem converts block.Block to stackitem.Item
|
// BlockToStackItem converts block.Block to stackitem.Item.
|
||||||
func BlockToStackItem(b *block.Block) stackitem.Item {
|
func BlockToStackItem(b *block.Block) stackitem.Item {
|
||||||
return stackitem.NewArray([]stackitem.Item{
|
return stackitem.NewArray([]stackitem.Item{
|
||||||
stackitem.NewByteArray(b.Hash().BytesBE()),
|
stackitem.NewByteArray(b.Hash().BytesBE()),
|
||||||
|
@ -213,7 +206,7 @@ func BlockToStackItem(b *block.Block) stackitem.Item {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransactionToStackItem converts transaction.Transaction to stackitem.Item
|
// TransactionToStackItem converts transaction.Transaction to stackitem.Item.
|
||||||
func TransactionToStackItem(t *transaction.Transaction) stackitem.Item {
|
func TransactionToStackItem(t *transaction.Transaction) stackitem.Item {
|
||||||
return stackitem.NewArray([]stackitem.Item{
|
return stackitem.NewArray([]stackitem.Item{
|
||||||
stackitem.NewByteArray(t.Hash().BytesBE()),
|
stackitem.NewByteArray(t.Hash().BytesBE()),
|
||||||
|
|
|
@ -409,14 +409,14 @@ func (m *Management) GetMinimumDeploymentFee(dao dao.DAO) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Management) setMinimumDeploymentFee(ic *interop.Context, args []stackitem.Item) stackitem.Item {
|
func (m *Management) setMinimumDeploymentFee(ic *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
value := toUint32(args[0])
|
value := toBigInt(args[0])
|
||||||
if value < 0 {
|
if value.Sign() < 0 {
|
||||||
panic(fmt.Errorf("MinimumDeploymentFee cannot be negative"))
|
panic("MinimumDeploymentFee cannot be negative")
|
||||||
}
|
}
|
||||||
if !m.NEO.checkCommittee(ic) {
|
if !m.NEO.checkCommittee(ic) {
|
||||||
panic("invalid committee signature")
|
panic("invalid committee signature")
|
||||||
}
|
}
|
||||||
err := setIntWithKey(m.ID, ic.DAO, keyMinimumDeploymentFee, int64(value))
|
err := ic.DAO.PutStorageItem(m.ID, keyMinimumDeploymentFee, bigint.ToBytes(value))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -539,7 +539,6 @@ func (m *Management) getNextContractID(d dao.DAO) (int32, error) {
|
||||||
si := d.GetStorageItem(m.ID, keyNextAvailableID)
|
si := d.GetStorageItem(m.ID, keyNextAvailableID)
|
||||||
if si == nil {
|
if si == nil {
|
||||||
return 0, errors.New("nextAvailableID is not initialized")
|
return 0, errors.New("nextAvailableID is not initialized")
|
||||||
|
|
||||||
}
|
}
|
||||||
id := bigint.FromBytes(si)
|
id := bigint.FromBytes(si)
|
||||||
ret := int32(id.Int64())
|
ret := int32(id.Int64())
|
||||||
|
|
|
@ -18,7 +18,8 @@ import (
|
||||||
func TestDeployGetUpdateDestroyContract(t *testing.T) {
|
func TestDeployGetUpdateDestroyContract(t *testing.T) {
|
||||||
mgmt := newManagement()
|
mgmt := newManagement()
|
||||||
d := dao.NewCached(dao.NewSimple(storage.NewMemoryStore(), false))
|
d := dao.NewCached(dao.NewSimple(storage.NewMemoryStore(), false))
|
||||||
mgmt.Initialize(&interop.Context{DAO: d})
|
err := mgmt.Initialize(&interop.Context{DAO: d})
|
||||||
|
require.NoError(t, err)
|
||||||
script := []byte{byte(opcode.RET)}
|
script := []byte{byte(opcode.RET)}
|
||||||
sender := util.Uint160{1, 2, 3}
|
sender := util.Uint160{1, 2, 3}
|
||||||
ne, err := nef.NewFile(script)
|
ne, err := nef.NewFile(script)
|
||||||
|
|
|
@ -64,8 +64,8 @@ const (
|
||||||
var (
|
var (
|
||||||
// Lookahead is not supported by Go, but it is simple `(?=.{3,255}$)`,
|
// Lookahead is not supported by Go, but it is simple `(?=.{3,255}$)`,
|
||||||
// so we check name length explicitly.
|
// so we check name length explicitly.
|
||||||
nameRegex = regexp.MustCompile("^([a-z0-9]{1,62}\\.)+[a-z][a-z0-9]{0,15}$")
|
nameRegex = regexp.MustCompile(`^([a-z0-9]{1,62}\.)+[a-z][a-z0-9]{0,15}$`)
|
||||||
ipv4Regex = regexp.MustCompile("^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])$")
|
ipv4Regex = regexp.MustCompile(`^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])$`)
|
||||||
ipv6Regex = regexp.MustCompile("(?:^)(([0-9a-f]{1,4}:){7,7}[0-9a-f]{1,4}|([0-9a-f]{1,4}:){1,7}:|([0-9a-f]{1,4}:){1,6}:[0-9a-f]{1,4}|([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}|([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}|([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}|([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}|[0-9a-f]{1,4}:((:[0-9a-f]{1,4}){1,6})|:((:[0-9a-f]{1,4}){1,7}|:))$")
|
ipv6Regex = regexp.MustCompile("(?:^)(([0-9a-f]{1,4}:){7,7}[0-9a-f]{1,4}|([0-9a-f]{1,4}:){1,7}:|([0-9a-f]{1,4}:){1,6}:[0-9a-f]{1,4}|([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}|([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}|([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}|([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}|[0-9a-f]{1,4}:((:[0-9a-f]{1,4}){1,6})|:((:[0-9a-f]{1,4}){1,7}|:))$")
|
||||||
rootRegex = regexp.MustCompile("^[a-z][a-z0-9]{0,15}$")
|
rootRegex = regexp.MustCompile("^[a-z][a-z0-9]{0,15}$")
|
||||||
)
|
)
|
||||||
|
@ -565,7 +565,7 @@ func (s *nameState) EncodeBinary(w *io.BinWriter) {
|
||||||
func (s *nameState) DecodeBinary(r *io.BinReader) {
|
func (s *nameState) DecodeBinary(r *io.BinReader) {
|
||||||
item := stackitem.DecodeBinaryStackItem(r)
|
item := stackitem.DecodeBinaryStackItem(r)
|
||||||
if r.Err == nil {
|
if r.Err == nil {
|
||||||
s.FromStackItem(item)
|
r.Err = s.FromStackItem(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,7 +626,6 @@ func domainFromString(name string) (string, bool) {
|
||||||
return name, true
|
return name, true
|
||||||
}
|
}
|
||||||
return name[i+1:], true
|
return name[i+1:], true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func toDomain(name string) string {
|
func toDomain(name string) string {
|
||||||
|
@ -700,7 +699,7 @@ func (sl stringList) EncodeBinary(w *io.BinWriter) {
|
||||||
func (sl *stringList) DecodeBinary(r *io.BinReader) {
|
func (sl *stringList) DecodeBinary(r *io.BinReader) {
|
||||||
item := stackitem.DecodeBinaryStackItem(r)
|
item := stackitem.DecodeBinaryStackItem(r)
|
||||||
if r.Err == nil {
|
if r.Err == nil {
|
||||||
sl.FromStackItem(item)
|
r.Err = sl.FromStackItem(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -711,17 +710,6 @@ func (sl stringList) index(s string) (int, bool) {
|
||||||
return index, index < len(sl) && sl[index] == s
|
return index, index < len(sl) && sl[index] == s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sl *stringList) remove(s string) bool {
|
|
||||||
index, has := sl.index(s)
|
|
||||||
if !has {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
copy((*sl)[index:], (*sl)[index+1:])
|
|
||||||
*sl = (*sl)[:len(*sl)-1]
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sl *stringList) add(s string) bool {
|
func (sl *stringList) add(s string) bool {
|
||||||
index, has := sl.index(s)
|
index, has := sl.index(s)
|
||||||
if has {
|
if has {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// The specification is following C# code:
|
// The specification is following C# code:
|
||||||
// string domain = string.Join('.', name.Split('.')[^2..]);
|
// string domain = string.Join('.', name.Split('.')[^2..]);
|
||||||
func TestParseDomain(t *testing.T) {
|
func TestParseDomain(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
@ -337,7 +337,6 @@ func (n *NEO) PostPersist(ic *interop.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if n.gasPerBlockChanged.Load().(bool) {
|
if n.gasPerBlockChanged.Load().(bool) {
|
||||||
gr, err := n.getSortedGASRecordFromDAO(ic.DAO)
|
gr, err := n.getSortedGASRecordFromDAO(ic.DAO)
|
||||||
|
|
|
@ -305,6 +305,8 @@ func (n *nonfungible) postTransfer(ic *interop.Context, from, to *util.Uint160,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ = (*nonfungible).burn // fix unused warning
|
||||||
|
|
||||||
func (n *nonfungible) burn(ic *interop.Context, tokenID []byte) {
|
func (n *nonfungible) burn(ic *interop.Context, tokenID []byte) {
|
||||||
key := n.getTokenKey(tokenID)
|
key := n.getTokenKey(tokenID)
|
||||||
n.burnByKey(ic, key)
|
n.burnByKey(ic, key)
|
||||||
|
|
|
@ -56,7 +56,7 @@ const (
|
||||||
maxFilterLength = 128
|
maxFilterLength = 128
|
||||||
maxCallbackLength = 32
|
maxCallbackLength = 32
|
||||||
maxUserDataLength = 512
|
maxUserDataLength = 512
|
||||||
// maxRequestsCount is the maximum number of requests per URL
|
// maxRequestsCount is the maximum number of requests per URL.
|
||||||
maxRequestsCount = 256
|
maxRequestsCount = 256
|
||||||
|
|
||||||
// DefaultOracleRequestPrice is default amount GAS needed for oracle request.
|
// DefaultOracleRequestPrice is default amount GAS needed for oracle request.
|
||||||
|
@ -520,7 +520,7 @@ func (o *Oracle) getSerializableFromDAO(d dao.DAO, key []byte, item io.Serializa
|
||||||
return getSerializableFromDAO(o.ID, d, key, item)
|
return getSerializableFromDAO(o.ID, d, key, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateCache updates cached Oracle values if they've been changed
|
// updateCache updates cached Oracle values if they've been changed.
|
||||||
func (o *Oracle) updateCache(d dao.DAO) error {
|
func (o *Oracle) updateCache(d dao.DAO) error {
|
||||||
orc, _ := o.Module.Load().(services.Oracle)
|
orc, _ := o.Module.Load().(services.Oracle)
|
||||||
if orc == nil {
|
if orc == nil {
|
||||||
|
|
|
@ -243,7 +243,7 @@ func (p *Policy) isBlocked(ic *interop.Context, args []stackitem.Item) stackitem
|
||||||
return stackitem.NewBool(p.IsBlockedInternal(ic.DAO, hash))
|
return stackitem.NewBool(p.IsBlockedInternal(ic.DAO, hash))
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsBlockedInternal checks whether provided account is blocked
|
// IsBlockedInternal checks whether provided account is blocked.
|
||||||
func (p *Policy) IsBlockedInternal(dao dao.DAO, hash util.Uint160) bool {
|
func (p *Policy) IsBlockedInternal(dao dao.DAO, hash util.Uint160) bool {
|
||||||
p.lock.RLock()
|
p.lock.RLock()
|
||||||
defer p.lock.RUnlock()
|
defer p.lock.RUnlock()
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package native
|
package native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
|
@ -36,34 +34,6 @@ func putSerializableToDAO(id int32, d dao.DAO, key []byte, item io.Serializable)
|
||||||
return d.PutStorageItem(id, key, w.Bytes())
|
return d.PutStorageItem(id, key, w.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func getInt64WithKey(id int32, d dao.DAO, key []byte, defaultValue int64) int64 {
|
|
||||||
si := d.GetStorageItem(id, key)
|
|
||||||
if si == nil {
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
return int64(binary.LittleEndian.Uint64(si))
|
|
||||||
}
|
|
||||||
|
|
||||||
func setInt64WithKey(id int32, dao dao.DAO, key []byte, value int64) error {
|
|
||||||
si := make(state.StorageItem, 8)
|
|
||||||
binary.LittleEndian.PutUint64(si, uint64(value))
|
|
||||||
return dao.PutStorageItem(id, key, si)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUint32WithKey(id int32, dao dao.DAO, key []byte, defaultValue uint32) uint32 {
|
|
||||||
si := dao.GetStorageItem(id, key)
|
|
||||||
if si == nil {
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
return binary.LittleEndian.Uint32(si)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setUint32WithKey(id int32, dao dao.DAO, key []byte, value uint32) error {
|
|
||||||
si := make(state.StorageItem, 4)
|
|
||||||
binary.LittleEndian.PutUint32(si, value)
|
|
||||||
return dao.PutStorageItem(id, key, si)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setIntWithKey(id int32, dao dao.DAO, key []byte, value int64) error {
|
func setIntWithKey(id int32, dao dao.DAO, key []byte, value int64) error {
|
||||||
return dao.PutStorageItem(id, key, bigint.ToBytes(big.NewInt(value)))
|
return dao.PutStorageItem(id, key, bigint.ToBytes(big.NewInt(value)))
|
||||||
}
|
}
|
||||||
|
@ -72,7 +42,6 @@ func getIntWithKey(id int32, dao dao.DAO, key []byte) int64 {
|
||||||
si := dao.GetStorageItem(id, key)
|
si := dao.GetStorageItem(id, key)
|
||||||
if si == nil {
|
if si == nil {
|
||||||
panic(fmt.Errorf("item with id = %d and key = %s is not initialized", id, hex.EncodeToString(key)))
|
panic(fmt.Errorf("item with id = %d and key = %s is not initialized", id, hex.EncodeToString(key)))
|
||||||
|
|
||||||
}
|
}
|
||||||
return bigint.FromBytes(si).Int64()
|
return bigint.FromBytes(si).Int64()
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,6 @@ func TestDesignate_DesignateAsRoleTx(t *testing.T) {
|
||||||
bc.setNodesByRole(t, true, noderoles.NeoFSAlphabet, pubs)
|
bc.setNodesByRole(t, true, noderoles.NeoFSAlphabet, pubs)
|
||||||
bc.getNodesByRole(t, true, noderoles.NeoFSAlphabet, bc.BlockHeight()+1, 1)
|
bc.getNodesByRole(t, true, noderoles.NeoFSAlphabet, bc.BlockHeight()+1, 1)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDesignate_DesignateAsRole(t *testing.T) {
|
func TestDesignate_DesignateAsRole(t *testing.T) {
|
||||||
|
@ -130,10 +129,10 @@ func TestDesignate_DesignateAsRole(t *testing.T) {
|
||||||
ic.SpawnVM()
|
ic.SpawnVM()
|
||||||
ic.VM.LoadScript([]byte{byte(opcode.RET)})
|
ic.VM.LoadScript([]byte{byte(opcode.RET)})
|
||||||
|
|
||||||
pubs, index, err := des.GetDesignatedByRole(bc.dao, 0xFF, 255)
|
_, _, err := des.GetDesignatedByRole(bc.dao, 0xFF, 255)
|
||||||
require.True(t, errors.Is(err, native.ErrInvalidRole), "got: %v", err)
|
require.True(t, errors.Is(err, native.ErrInvalidRole), "got: %v", err)
|
||||||
|
|
||||||
pubs, index, err = des.GetDesignatedByRole(bc.dao, noderoles.Oracle, 255)
|
pubs, index, err := des.GetDesignatedByRole(bc.dao, noderoles.Oracle, 255)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 0, len(pubs))
|
require.Equal(t, 0, len(pubs))
|
||||||
require.Equal(t, uint32(0), index)
|
require.Equal(t, uint32(0), index)
|
||||||
|
|
|
@ -577,7 +577,6 @@ func TestContractDestroy(t *testing.T) {
|
||||||
t.Run("check contract", func(t *testing.T) {
|
t.Run("check contract", func(t *testing.T) {
|
||||||
checkContractState(t, bc, cs1.Hash, nil)
|
checkContractState(t, bc, cs1.Hash, nil)
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,6 @@ func TestExpiration(t *testing.T) {
|
||||||
aer, err = bc.GetAppExecResults(tx.Hash(), trigger.Application)
|
aer, err = bc.GetAppExecResults(tx.Hash(), trigger.Application)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
checkResult(t, &aer[0], stackitem.Null{})
|
checkResult(t, &aer[0], stackitem.Null{})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const secondsInYear = 365 * 24 * 3600
|
const secondsInYear = 365 * 24 * 3600
|
||||||
|
|
|
@ -122,7 +122,8 @@ func TestNEO_Vote(t *testing.T) {
|
||||||
ic.VM.Load(priv.PublicKey().GetVerificationScript())
|
ic.VM.Load(priv.PublicKey().GetVerificationScript())
|
||||||
require.NoError(t, neo.VoteInternal(ic, h, candidates[0]))
|
require.NoError(t, neo.VoteInternal(ic, h, candidates[0]))
|
||||||
|
|
||||||
ic.DAO.Persist()
|
_, err = ic.DAO.Persist()
|
||||||
|
require.NoError(t, err)
|
||||||
advanceChain(t)
|
advanceChain(t)
|
||||||
pubs, err = neo.ComputeNextBlockValidators(bc, ic.DAO)
|
pubs, err = neo.ComputeNextBlockValidators(bc, ic.DAO)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -225,7 +226,6 @@ func TestNEO_CalculateBonus(t *testing.T) {
|
||||||
res, err := neo.CalculateNEOHolderReward(ic.DAO, big.NewInt(100), 5, 15)
|
res, err := neo.CalculateNEOHolderReward(ic.DAO, big.NewInt(100), 5, 15)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.EqualValues(t, (100*5*5/10)+(100*5*1/10), res.Int64())
|
require.EqualValues(t, (100*5*5/10)+(100*5*1/10), res.Int64())
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,8 @@ func TestNotaryContractPipeline(t *testing.T) {
|
||||||
checkResult(t, balance, stackitem.Make(3*transaction.NotaryServiceFeePerKey))
|
checkResult(t, balance, stackitem.Make(3*transaction.NotaryServiceFeePerKey))
|
||||||
|
|
||||||
// `withdraw`: unlock deposit and transfer GAS back to owner
|
// `withdraw`: unlock deposit and transfer GAS back to owner
|
||||||
chain.genBlocks(depositLock)
|
_, err = chain.genBlocks(depositLock)
|
||||||
|
require.NoError(t, err)
|
||||||
withdrawRes, err = invokeContractMethod(chain, 100000000, notaryHash, "withdraw", testchain.MultisigScriptHash(), testchain.MultisigScriptHash())
|
withdrawRes, err = invokeContractMethod(chain, 100000000, notaryHash, "withdraw", testchain.MultisigScriptHash(), testchain.MultisigScriptHash())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
checkResult(t, withdrawRes, stackitem.NewBool(true))
|
checkResult(t, withdrawRes, stackitem.NewBool(true))
|
||||||
|
|
|
@ -145,7 +145,8 @@ func TestNotary(t *testing.T) {
|
||||||
VerificationScript: []byte{},
|
VerificationScript: []byte{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
requester.SignTx(testchain.Network(), fallback)
|
err = requester.SignTx(testchain.Network(), fallback)
|
||||||
|
require.NoError(t, err)
|
||||||
return fallback
|
return fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ func (c *Contract) EncodeBinary(w *io.BinWriter) {
|
||||||
stackitem.EncodeBinaryStackItem(si, w)
|
stackitem.EncodeBinaryStackItem(si, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToStackItem converts state.Contract to stackitem.Item
|
// ToStackItem converts state.Contract to stackitem.Item.
|
||||||
func (c *Contract) ToStackItem() (stackitem.Item, error) {
|
func (c *Contract) ToStackItem() (stackitem.Item, error) {
|
||||||
rawNef, err := c.NEF.Bytes()
|
rawNef, err := c.NEF.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -129,7 +129,7 @@ func (ne *NotificationEvent) UnmarshalJSON(data []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// appExecResultAux is an auxiliary struct for JSON marshalling
|
// appExecResultAux is an auxiliary struct for JSON marshalling.
|
||||||
type appExecResultAux struct {
|
type appExecResultAux struct {
|
||||||
Container util.Uint256 `json:"container"`
|
Container util.Uint256 `json:"container"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,6 @@ func TestMarshalUnmarshalJSONNotificationEvent(t *testing.T) {
|
||||||
err := json.Unmarshal([]byte(errCase), new(NotificationEvent))
|
err := json.Unmarshal([]byte(errCase), new(NotificationEvent))
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,5 +76,4 @@ func TestOracleRequest_EncodeBinary(t *testing.T) {
|
||||||
t.Run("Method", runInvalid(5, stackitem.NewMap()))
|
t.Run("Method", runInvalid(5, stackitem.NewMap()))
|
||||||
t.Run("UserData", runInvalid(6, stackitem.NewMap()))
|
t.Run("UserData", runInvalid(6, stackitem.NewMap()))
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,7 @@ func TestStateRootFull(t *testing.T) {
|
||||||
require.Eventually(t, func() bool { return lastHeight.Load() == 2 }, time.Second, time.Millisecond)
|
require.Eventually(t, func() bool { return lastHeight.Load() == 2 }, time.Second, time.Millisecond)
|
||||||
checkVoteBroadcasted(t, bc, lastValidated.Load().(*payload.Extensible), 2, 1)
|
checkVoteBroadcasted(t, bc, lastValidated.Load().(*payload.Extensible), 2, 1)
|
||||||
_, err = persistBlock(bc)
|
_, err = persistBlock(bc)
|
||||||
|
require.NoError(t, err)
|
||||||
require.Eventually(t, func() bool { return lastHeight.Load() == 3 }, time.Second, time.Millisecond)
|
require.Eventually(t, func() bool { return lastHeight.Load() == 3 }, time.Second, time.Millisecond)
|
||||||
checkVoteBroadcasted(t, bc, lastValidated.Load().(*payload.Extensible), 3, 1)
|
checkVoteBroadcasted(t, bc, lastValidated.Load().(*payload.Extensible), 3, 1)
|
||||||
|
|
||||||
|
@ -257,6 +258,7 @@ func checkVoteBroadcasted(t *testing.T, bc *Blockchain, p *payload.Extensible,
|
||||||
require.Equal(t, int32(valIndex), vote.ValidatorIndex)
|
require.Equal(t, int32(valIndex), vote.ValidatorIndex)
|
||||||
|
|
||||||
pubs, _, err := bc.contracts.Designate.GetDesignatedByRole(bc.dao, noderoles.StateValidator, bc.BlockHeight())
|
pubs, _, err := bc.contracts.Designate.GetDesignatedByRole(bc.dao, noderoles.StateValidator, bc.BlockHeight())
|
||||||
|
require.NoError(t, err)
|
||||||
require.True(t, len(pubs) > int(valIndex))
|
require.True(t, len(pubs) > int(valIndex))
|
||||||
require.True(t, pubs[valIndex].VerifyHashable(vote.Signature, uint32(netmode.UnitTestNet), r))
|
require.True(t, pubs[valIndex].VerifyHashable(vote.Signature, uint32(netmode.UnitTestNet), r))
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,12 @@ type BadgerDBStore struct {
|
||||||
db *badger.DB
|
db *badger.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
// BadgerDBBatch is a wrapper around badger.WriteBatch, compatible with Batch interface
|
// BadgerDBBatch is a wrapper around badger.WriteBatch, compatible with Batch interface.
|
||||||
type BadgerDBBatch struct {
|
type BadgerDBBatch struct {
|
||||||
batch *badger.WriteBatch
|
batch *badger.WriteBatch
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete implements the Batch interface
|
// Delete implements the Batch interface.
|
||||||
func (b *BadgerDBBatch) Delete(key []byte) {
|
func (b *BadgerDBBatch) Delete(key []byte) {
|
||||||
err := b.batch.Delete(key)
|
err := b.batch.Delete(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -30,7 +30,7 @@ func (b *BadgerDBBatch) Delete(key []byte) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put implements the Batch interface
|
// Put implements the Batch interface.
|
||||||
func (b *BadgerDBBatch) Put(key, value []byte) {
|
func (b *BadgerDBBatch) Put(key, value []byte) {
|
||||||
keycopy := make([]byte, len(key))
|
keycopy := make([]byte, len(key))
|
||||||
copy(keycopy, key)
|
copy(keycopy, key)
|
||||||
|
|
|
@ -69,7 +69,7 @@ func (k KeyPrefix) Bytes() []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendPrefix appends byteslice b to the given KeyPrefix.
|
// AppendPrefix appends byteslice b to the given KeyPrefix.
|
||||||
// AppendKeyPrefix(SYSVersion, []byte{0x00, 0x01})
|
// AppendKeyPrefix(SYSVersion, []byte{0x00, 0x01}).
|
||||||
func AppendPrefix(k KeyPrefix, b []byte) []byte {
|
func AppendPrefix(k KeyPrefix, b []byte) []byte {
|
||||||
dest := make([]byte, len(b)+1)
|
dest := make([]byte, len(b)+1)
|
||||||
dest[0] = byte(k)
|
dest[0] = byte(k)
|
||||||
|
@ -78,7 +78,7 @@ func AppendPrefix(k KeyPrefix, b []byte) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendPrefixInt append int n to the given KeyPrefix.
|
// AppendPrefixInt append int n to the given KeyPrefix.
|
||||||
//AppendPrefixInt(SYSCurrentHeader, 10001)
|
// AppendPrefixInt(SYSCurrentHeader, 10001)
|
||||||
func AppendPrefixInt(k KeyPrefix, n int) []byte {
|
func AppendPrefixInt(k KeyPrefix, n int) []byte {
|
||||||
b := make([]byte, 4)
|
b := make([]byte, 4)
|
||||||
binary.LittleEndian.PutUint32(b, uint32(n))
|
binary.LittleEndian.PutUint32(b, uint32(n))
|
||||||
|
|
|
@ -6,9 +6,9 @@ package transaction
|
||||||
type AttrType uint8
|
type AttrType uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ReservedLowerBound is the lower bound of reserved attribute types
|
// ReservedLowerBound is the lower bound of reserved attribute types.
|
||||||
ReservedLowerBound = 0xe0
|
ReservedLowerBound = 0xe0
|
||||||
// ReservedUpperBound is the upper bound of reserved attribute types
|
// ReservedUpperBound is the upper bound of reserved attribute types.
|
||||||
ReservedUpperBound = 0xff
|
ReservedUpperBound = 0xff
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// tx from C# privnet 0x25426643feed564cd3e57f346d6c68692f5622b3063da11c5572d99ee1a5b49a
|
// tx from C# privnet 0x25426643feed564cd3e57f346d6c68692f5622b3063da11c5572d99ee1a5b49a.
|
||||||
rawInvocationTX = "ANgkvBnA2KcAAAAAACCqRAAAAAAA6AMAAAHe7nnBifMAmLC6ai65CzqSWKbH/wEAXwsDAEDZ3YhNCgAMFIDOx7b1tW9QV49zfxYtOrFNRmUNDBTe7nnBifMAmLC6ai65CzqSWKbH/xTAHwwIdHJhbnNmZXIMFM924ovQBixKR47jVWEBExnzz6TSQWJ9W1I5AcYMQNafQPvPYQuqk3yCFwz8+18XCjnr8F8Rqx8e5IoQIkxjG9TjuvZm1KKGDn2UbFJnMey/FPLqezK8nbbJw2Eg10kMQKXrVyD3fs38e6Mqwsy7bAkxLsLnhvMnerbYLOqWW/DdinzT1RKAoOz5b7dAPusj5IWzQ6EifSCigJRTp//XdaMMQOv1d15PkIZM7wIvQmKDNxNy5yzQYFyoezx9Og7rM+64J9LtaHp3LFIKKNPgDhL7sFR1bd2w7vzbyR7V+Pyg3GaTEwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl"
|
rawInvocationTX = "ANgkvBnA2KcAAAAAACCqRAAAAAAA6AMAAAHe7nnBifMAmLC6ai65CzqSWKbH/wEAXwsDAEDZ3YhNCgAMFIDOx7b1tW9QV49zfxYtOrFNRmUNDBTe7nnBifMAmLC6ai65CzqSWKbH/xTAHwwIdHJhbnNmZXIMFM924ovQBixKR47jVWEBExnzz6TSQWJ9W1I5AcYMQNafQPvPYQuqk3yCFwz8+18XCjnr8F8Rqx8e5IoQIkxjG9TjuvZm1KKGDn2UbFJnMey/FPLqezK8nbbJw2Eg10kMQKXrVyD3fs38e6Mqwsy7bAkxLsLnhvMnerbYLOqWW/DdinzT1RKAoOz5b7dAPusj5IWzQ6EifSCigJRTp//XdaMMQOv1d15PkIZM7wIvQmKDNxNy5yzQYFyoezx9Og7rM+64J9LtaHp3LFIKKNPgDhL7sFR1bd2w7vzbyR7V+Pyg3GaTEwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFEF7zmyl"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The maximum number of AllowedContracts or AllowedGroups
|
// The maximum number of AllowedContracts or AllowedGroups.
|
||||||
const maxSubitems = 16
|
const maxSubitems = 16
|
||||||
|
|
||||||
// Signer implements a Transaction signer.
|
// Signer implements a Transaction signer.
|
||||||
|
|
|
@ -230,7 +230,7 @@ func (t *Transaction) DecodeHashableFields(buf []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes converts the transaction to []byte
|
// Bytes converts the transaction to []byte.
|
||||||
func (t *Transaction) Bytes() []byte {
|
func (t *Transaction) Bytes() []byte {
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
t.EncodeBinary(buf.BinWriter)
|
t.EncodeBinary(buf.BinWriter)
|
||||||
|
@ -240,7 +240,7 @@ func (t *Transaction) Bytes() []byte {
|
||||||
return buf.Bytes()
|
return buf.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTransactionFromBytes decodes byte array into *Transaction
|
// NewTransactionFromBytes decodes byte array into *Transaction.
|
||||||
func NewTransactionFromBytes(b []byte) (*Transaction, error) {
|
func NewTransactionFromBytes(b []byte) (*Transaction, error) {
|
||||||
tx := &Transaction{}
|
tx := &Transaction{}
|
||||||
r := io.NewBinReaderFromBuf(b)
|
r := io.NewBinReaderFromBuf(b)
|
||||||
|
@ -257,7 +257,7 @@ func NewTransactionFromBytes(b []byte) (*Transaction, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FeePerByte returns NetworkFee of the transaction divided by
|
// FeePerByte returns NetworkFee of the transaction divided by
|
||||||
// its size
|
// its size.
|
||||||
func (t *Transaction) FeePerByte() int64 {
|
func (t *Transaction) FeePerByte() int64 {
|
||||||
return t.NetworkFee / int64(t.Size())
|
return t.NetworkFee / int64(t.Size())
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ func (t *Transaction) Sender() util.Uint160 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// transactionJSON is a wrapper for Transaction and
|
// transactionJSON is a wrapper for Transaction and
|
||||||
// used for correct marhalling of transaction.Data
|
// used for correct marhalling of transaction.Data.
|
||||||
type transactionJSON struct {
|
type transactionJSON struct {
|
||||||
TxID util.Uint256 `json:"hash"`
|
TxID util.Uint256 `json:"hash"`
|
||||||
Size int `json:"size"`
|
Size int `json:"size"`
|
||||||
|
|
|
@ -14,17 +14,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// governingTokenTX represents transaction that is used to create
|
|
||||||
// governing (NEO) token. It's a part of the genesis block.
|
|
||||||
governingTokenTX transaction.Transaction
|
|
||||||
|
|
||||||
// utilityTokenTX represents transaction that is used to create
|
|
||||||
// utility (GAS) token. It's a part of the genesis block. It's mostly
|
|
||||||
// useful for its hash that represents GAS asset ID.
|
|
||||||
utilityTokenTX transaction.Transaction
|
|
||||||
)
|
|
||||||
|
|
||||||
// createGenesisBlock creates a genesis block based on the given configuration.
|
// createGenesisBlock creates a genesis block based on the given configuration.
|
||||||
func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error) {
|
func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error) {
|
||||||
validators, err := validatorsFromConfig(cfg)
|
validators, err := validatorsFromConfig(cfg)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"golang.org/x/crypto/ripemd160"
|
"golang.org/x/crypto/ripemd160" //nolint:staticcheck // SA1019: package golang.org/x/crypto/ripemd160 is deprecated
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hashable represents an object which can be hashed. Usually these objects
|
// Hashable represents an object which can be hashed. Usually these objects
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
|
|
||||||
func TestNEP2Encrypt(t *testing.T) {
|
func TestNEP2Encrypt(t *testing.T) {
|
||||||
for _, testCase := range keytestcases.Arr {
|
for _, testCase := range keytestcases.Arr {
|
||||||
|
|
||||||
privKey, err := NewPrivateKeyFromHex(testCase.PrivateKey)
|
privKey, err := NewPrivateKeyFromHex(testCase.PrivateKey)
|
||||||
if testCase.Invalid {
|
if testCase.Invalid {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
|
@ -161,7 +161,6 @@ func (p *PublicKey) getBytes(compressed bool) []byte {
|
||||||
prefix = 0x04
|
prefix = 0x04
|
||||||
yBytes := p.Y.Bytes()
|
yBytes := p.Y.Bytes()
|
||||||
copy(res[1+coordLen+coordLen-len(yBytes):], yBytes)
|
copy(res[1+coordLen+coordLen-len(yBytes):], yBytes)
|
||||||
|
|
||||||
}
|
}
|
||||||
res[0] = prefix
|
res[0] = prefix
|
||||||
|
|
||||||
|
@ -204,7 +203,7 @@ func NewPublicKeyFromASN1(data []byte) (*PublicKey, error) {
|
||||||
// 1. Secp256k1 (Koblitz curve): y² = x³ + b,
|
// 1. Secp256k1 (Koblitz curve): y² = x³ + b,
|
||||||
// 2. Secp256r1 (Random curve): y² = x³ - 3x + b.
|
// 2. Secp256r1 (Random curve): y² = x³ - 3x + b.
|
||||||
// To decode compressed curve point we perform the following operation: y = sqrt(x³ + ax + b mod p)
|
// To decode compressed curve point we perform the following operation: y = sqrt(x³ + ax + b mod p)
|
||||||
// where `p` denotes the order of the underlying curve field
|
// where `p` denotes the order of the underlying curve field.
|
||||||
func decodeCompressedY(x *big.Int, ylsb uint, curve elliptic.Curve) (*big.Int, error) {
|
func decodeCompressedY(x *big.Int, ylsb uint, curve elliptic.Curve) (*big.Int, error) {
|
||||||
var a *big.Int
|
var a *big.Int
|
||||||
switch curve.(type) {
|
switch curve.(type) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
const (
|
const (
|
||||||
// MaxBytesLen is the maximum length of serialized integer suitable for Neo VM.
|
// MaxBytesLen is the maximum length of serialized integer suitable for Neo VM.
|
||||||
MaxBytesLen = 33 // 32 bytes for 256-bit integer plus 1 if padding needed
|
MaxBytesLen = 33 // 32 bytes for 256-bit integer plus 1 if padding needed
|
||||||
// wordSizeBytes is a size of a big.Word (uint) in bytes.`
|
// wordSizeBytes is a size of a big.Word (uint) in bytes.
|
||||||
wordSizeBytes = bits.UintSize / 8
|
wordSizeBytes = bits.UintSize / 8
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ var stringCases = []struct {
|
||||||
|
|
||||||
// this cases are from stdlib
|
// this cases are from stdlib
|
||||||
// https://github.com/dotnet/runtime/blob/master/src/libraries/System.Runtime.Numerics/tests/BigInteger/ToByteArray.cs#L96
|
// https://github.com/dotnet/runtime/blob/master/src/libraries/System.Runtime.Numerics/tests/BigInteger/ToByteArray.cs#L96
|
||||||
// note that they are in big-endian
|
// note that they are in big-endian.
|
||||||
var stdlibCases = []struct {
|
var stdlibCases = []struct {
|
||||||
numStr string
|
numStr string
|
||||||
buf []byte
|
buf []byte
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package fixedn
|
package fixedn
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -13,8 +12,6 @@ const (
|
||||||
decimals = 100000000
|
decimals = 100000000
|
||||||
)
|
)
|
||||||
|
|
||||||
var errInvalidString = errors.New("fixed8 must satisfy following regex \\d+(\\.\\d{1,8})?")
|
|
||||||
|
|
||||||
// Fixed8 represents a fixed-point number with precision 10^-8.
|
// Fixed8 represents a fixed-point number with precision 10^-8.
|
||||||
type Fixed8 int64
|
type Fixed8 int64
|
||||||
|
|
||||||
|
@ -68,7 +65,7 @@ func Fixed8FromFloat(val float64) Fixed8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fixed8FromString parses s which must be a fixed point number
|
// Fixed8FromString parses s which must be a fixed point number
|
||||||
// with precision up to 10^-8
|
// with precision up to 10^-8.
|
||||||
func Fixed8FromString(s string) (Fixed8, error) {
|
func Fixed8FromString(s string) (Fixed8, error) {
|
||||||
num, err := FromString(s, precision)
|
num, err := FromString(s, precision)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -31,7 +31,6 @@ func TestFixed8Add(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFixed8Sub(t *testing.T) {
|
func TestFixed8Sub(t *testing.T) {
|
||||||
|
|
||||||
a := Fixed8FromInt64(42)
|
a := Fixed8FromInt64(42)
|
||||||
b := Fixed8FromInt64(34)
|
b := Fixed8FromInt64(34)
|
||||||
|
|
||||||
|
|
|
@ -46,11 +46,11 @@ func JSONSerialize(item interface{}) []byte {
|
||||||
// JSONDeserialize deserializes value from json. It uses `jsonDeserialize` method of StdLib
|
// JSONDeserialize deserializes value from json. It uses `jsonDeserialize` method of StdLib
|
||||||
// native contract.
|
// native contract.
|
||||||
// It performs deserialization as follows:
|
// It performs deserialization as follows:
|
||||||
// strings -> []byte (string) from base64
|
// strings -> []byte (string) from base64
|
||||||
// integers -> (u)int* types
|
// integers -> (u)int* types
|
||||||
// null -> interface{}(nil)
|
// null -> interface{}(nil)
|
||||||
// arrays -> []interface{}
|
// arrays -> []interface{}
|
||||||
// maps -> map[string]interface{}
|
// maps -> map[string]interface{}
|
||||||
func JSONDeserialize(data []byte) interface{} {
|
func JSONDeserialize(data []byte) interface{} {
|
||||||
return contract.Call(interop.Hash160(Hash), "jsonDeserialize", contract.NoneFlag,
|
return contract.Call(interop.Hash160(Hash), "jsonDeserialize", contract.NoneFlag,
|
||||||
data)
|
data)
|
||||||
|
|
|
@ -13,5 +13,5 @@ type Hash256 []byte
|
||||||
type PublicKey []byte
|
type PublicKey []byte
|
||||||
|
|
||||||
// Interface represents interop interface type which is needed for
|
// Interface represents interop interface type which is needed for
|
||||||
// transparent handling of VM-internal types (e.g. storage.Context)
|
// transparent handling of VM-internal types (e.g. storage.Context).
|
||||||
type Interface interface{}
|
type Interface interface{}
|
||||||
|
|
|
@ -167,7 +167,7 @@ func (r *BinReader) ReadVarUint() uint64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadVarBytes reads the next set of bytes from the underlying reader.
|
// ReadVarBytes reads the next set of bytes from the underlying reader.
|
||||||
// ReadVarUInt() is used to determine how large that slice is
|
// ReadVarUInt() is used to determine how large that slice is.
|
||||||
func (r *BinReader) ReadVarBytes(maxSize ...int) []byte {
|
func (r *BinReader) ReadVarBytes(maxSize ...int) []byte {
|
||||||
n := r.ReadVarUint()
|
n := r.ReadVarUint()
|
||||||
ms := MaxArraySize
|
ms := MaxArraySize
|
||||||
|
|
|
@ -119,7 +119,6 @@ func (w *BinWriter) WriteVarUint(val uint64) {
|
||||||
w.WriteB(byte(0xfe))
|
w.WriteB(byte(0xfe))
|
||||||
w.WriteU32LE(uint32(val))
|
w.WriteU32LE(uint32(val))
|
||||||
return
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteB(byte(0xff))
|
w.WriteB(byte(0xff))
|
||||||
|
|
|
@ -5,18 +5,6 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
bit8 byte
|
|
||||||
ui8 uint8
|
|
||||||
ui16 uint16
|
|
||||||
ui32 uint32
|
|
||||||
ui64 uint64
|
|
||||||
i8 int8
|
|
||||||
i16 int16
|
|
||||||
i32 int32
|
|
||||||
i64 int64
|
|
||||||
)
|
|
||||||
|
|
||||||
// This structure is used to calculate the wire size of the serializable
|
// This structure is used to calculate the wire size of the serializable
|
||||||
// structure. It's an io.Writer that doesn't do any real writes, but instead
|
// structure. It's an io.Writer that doesn't do any real writes, but instead
|
||||||
// just counts the number of bytes to be written.
|
// just counts the number of bytes to be written.
|
||||||
|
@ -71,7 +59,7 @@ func GetVarSize(value interface{}) int {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
vser, ok := v.Interface().(Serializable)
|
vser, ok := v.Interface().(Serializable)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Sprintf("unable to calculate GetVarSize for a non-Serializable pointer"))
|
panic("unable to calculate GetVarSize for a non-Serializable pointer")
|
||||||
}
|
}
|
||||||
cw := counterWriter{}
|
cw := counterWriter{}
|
||||||
w := NewBinWriterFromIO(&cw)
|
w := NewBinWriterFromIO(&cw)
|
||||||
|
|
|
@ -6,10 +6,10 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MaxCapabilities is the maximum number of capabilities per payload
|
// MaxCapabilities is the maximum number of capabilities per payload.
|
||||||
const MaxCapabilities = 32
|
const MaxCapabilities = 32
|
||||||
|
|
||||||
// Capabilities is a list of Capability
|
// Capabilities is a list of Capability.
|
||||||
type Capabilities []Capability
|
type Capabilities []Capability
|
||||||
|
|
||||||
// DecodeBinary implements Serializable interface.
|
// DecodeBinary implements Serializable interface.
|
||||||
|
@ -49,7 +49,7 @@ func (cs Capabilities) checkUniqueCapabilities() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Capability describes network service available for node
|
// Capability describes network service available for node.
|
||||||
type Capability struct {
|
type Capability struct {
|
||||||
Type Type
|
Type Type
|
||||||
Data io.Serializable
|
Data io.Serializable
|
||||||
|
@ -80,7 +80,7 @@ func (c *Capability) EncodeBinary(bw *io.BinWriter) {
|
||||||
c.Data.EncodeBinary(bw)
|
c.Data.EncodeBinary(bw)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node represents full node capability with start height
|
// Node represents full node capability with start height.
|
||||||
type Node struct {
|
type Node struct {
|
||||||
StartHeight uint32
|
StartHeight uint32
|
||||||
}
|
}
|
||||||
|
@ -95,9 +95,9 @@ func (n *Node) EncodeBinary(bw *io.BinWriter) {
|
||||||
bw.WriteU32LE(n.StartHeight)
|
bw.WriteU32LE(n.StartHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server represents TCP or WS server capability with port
|
// Server represents TCP or WS server capability with port.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
// Port is the port this server is listening on
|
// Port is the port this server is listening on.
|
||||||
Port uint16
|
Port uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package capability
|
package capability
|
||||||
|
|
||||||
// Type represents node capability type
|
// Type represents node capability type.
|
||||||
type Type byte
|
type Type byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// TCPServer represents TCP node capability type
|
// TCPServer represents TCP node capability type.
|
||||||
TCPServer Type = 0x01
|
TCPServer Type = 0x01
|
||||||
// WSServer represents WebSocket node capability type
|
// WSServer represents WebSocket node capability type.
|
||||||
WSServer Type = 0x02
|
WSServer Type = 0x02
|
||||||
// FullNode represents full node capability type
|
// FullNode represents full node capability type.
|
||||||
FullNode Type = 0x10
|
FullNode Type = 0x10
|
||||||
)
|
)
|
||||||
|
|
|
@ -28,7 +28,7 @@ type Discoverer interface {
|
||||||
GoodPeers() []AddressWithCapabilities
|
GoodPeers() []AddressWithCapabilities
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddressWithCapabilities represents node address with its capabilities
|
// AddressWithCapabilities represents node address with its capabilities.
|
||||||
type AddressWithCapabilities struct {
|
type AddressWithCapabilities struct {
|
||||||
Address string
|
Address string
|
||||||
Capabilities capability.Capabilities
|
Capabilities capability.Capabilities
|
||||||
|
@ -94,7 +94,7 @@ func (d *DefaultDiscovery) PoolCount() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pushToPoolOrDrop tries to push address given into the pool, but if the pool
|
// pushToPoolOrDrop tries to push address given into the pool, but if the pool
|
||||||
// is already full, it just drops it
|
// is already full, it just drops it.
|
||||||
func (d *DefaultDiscovery) pushToPoolOrDrop(addr string) {
|
func (d *DefaultDiscovery) pushToPoolOrDrop(addr string) {
|
||||||
select {
|
select {
|
||||||
case d.pool <- addr:
|
case d.pool <- addr:
|
||||||
|
|
|
@ -197,12 +197,10 @@ func TestSeedDiscovery(t *testing.T) {
|
||||||
d := NewDefaultDiscovery(seeds, time.Second/10, ts)
|
d := NewDefaultDiscovery(seeds, time.Second/10, ts)
|
||||||
|
|
||||||
d.RequestRemote(len(seeds))
|
d.RequestRemote(len(seeds))
|
||||||
dialled := make([]string, 0)
|
|
||||||
for i := 0; i < connRetries*2; i++ {
|
for i := 0; i < connRetries*2; i++ {
|
||||||
for range seeds {
|
for range seeds {
|
||||||
select {
|
select {
|
||||||
case a := <-ts.dialCh:
|
case <-ts.dialCh:
|
||||||
dialled = append(dialled, a)
|
|
||||||
case <-time.After(time.Second):
|
case <-time.After(time.Second):
|
||||||
t.Fatalf("timeout expecting for transport dial")
|
t.Fatalf("timeout expecting for transport dial")
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import (
|
||||||
type testDiscovery struct {
|
type testDiscovery struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
bad []string
|
bad []string
|
||||||
good []string
|
|
||||||
connected []string
|
connected []string
|
||||||
unregistered []string
|
unregistered []string
|
||||||
backfill []string
|
backfill []string
|
||||||
|
|
|
@ -34,10 +34,10 @@ type Message struct {
|
||||||
StateRootInHeader bool
|
StateRootInHeader bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageFlag represents compression level of message payload
|
// MessageFlag represents compression level of message payload.
|
||||||
type MessageFlag byte
|
type MessageFlag byte
|
||||||
|
|
||||||
// Possible message flags
|
// Possible message flags.
|
||||||
const (
|
const (
|
||||||
Compressed MessageFlag = 1 << iota
|
Compressed MessageFlag = 1 << iota
|
||||||
None MessageFlag = 0
|
None MessageFlag = 0
|
||||||
|
@ -48,17 +48,17 @@ type CommandType byte
|
||||||
|
|
||||||
// Valid protocol commands used to send between nodes.
|
// Valid protocol commands used to send between nodes.
|
||||||
const (
|
const (
|
||||||
// handshaking
|
// Handshaking.
|
||||||
CMDVersion CommandType = 0x00
|
CMDVersion CommandType = 0x00
|
||||||
CMDVerack CommandType = 0x01
|
CMDVerack CommandType = 0x01
|
||||||
|
|
||||||
// connectivity
|
// Connectivity.
|
||||||
CMDGetAddr CommandType = 0x10
|
CMDGetAddr CommandType = 0x10
|
||||||
CMDAddr CommandType = 0x11
|
CMDAddr CommandType = 0x11
|
||||||
CMDPing CommandType = 0x18
|
CMDPing CommandType = 0x18
|
||||||
CMDPong CommandType = 0x19
|
CMDPong CommandType = 0x19
|
||||||
|
|
||||||
// synchronization
|
// Synchronization.
|
||||||
CMDGetHeaders CommandType = 0x20
|
CMDGetHeaders CommandType = 0x20
|
||||||
CMDHeaders CommandType = 0x21
|
CMDHeaders CommandType = 0x21
|
||||||
CMDGetBlocks CommandType = 0x24
|
CMDGetBlocks CommandType = 0x24
|
||||||
|
@ -73,13 +73,13 @@ const (
|
||||||
CMDP2PNotaryRequest = CommandType(payload.P2PNotaryRequestType)
|
CMDP2PNotaryRequest = CommandType(payload.P2PNotaryRequestType)
|
||||||
CMDReject CommandType = 0x2f
|
CMDReject CommandType = 0x2f
|
||||||
|
|
||||||
// SPV protocol
|
// SPV protocol.
|
||||||
CMDFilterLoad CommandType = 0x30
|
CMDFilterLoad CommandType = 0x30
|
||||||
CMDFilterAdd CommandType = 0x31
|
CMDFilterAdd CommandType = 0x31
|
||||||
CMDFilterClear CommandType = 0x32
|
CMDFilterClear CommandType = 0x32
|
||||||
CMDMerkleBlock CommandType = 0x38
|
CMDMerkleBlock CommandType = 0x38
|
||||||
|
|
||||||
// others
|
// Others.
|
||||||
CMDAlert CommandType = 0x40
|
CMDAlert CommandType = 0x40
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ func (m *Message) Bytes() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// tryCompressPayload sets message's compressed payload to serialized
|
// tryCompressPayload sets message's compressed payload to serialized
|
||||||
// payload and compresses it in case if its size exceeds CompressionMinSize
|
// payload and compresses it in case if its size exceeds CompressionMinSize.
|
||||||
func (m *Message) tryCompressPayload() error {
|
func (m *Message) tryCompressPayload() error {
|
||||||
if m.Payload == nil {
|
if m.Payload == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -2,7 +2,6 @@ package payload
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"math"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
|
@ -10,10 +9,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const maxExtensibleCategorySize = 32
|
||||||
maxExtensibleCategorySize = 32
|
|
||||||
maxExtensibleDataSize = math.MaxUint16
|
|
||||||
)
|
|
||||||
|
|
||||||
// Extensible represents payload containing arbitrary data.
|
// Extensible represents payload containing arbitrary data.
|
||||||
type Extensible struct {
|
type Extensible struct {
|
||||||
|
|
|
@ -6,13 +6,13 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetBlockByIndex payload
|
// GetBlockByIndex payload.
|
||||||
type GetBlockByIndex struct {
|
type GetBlockByIndex struct {
|
||||||
IndexStart uint32
|
IndexStart uint32
|
||||||
Count int16
|
Count int16
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGetBlockByIndex returns GetBlockByIndex payload with specified start index and count
|
// NewGetBlockByIndex returns GetBlockByIndex payload with specified start index and count.
|
||||||
func NewGetBlockByIndex(indexStart uint32, count int16) *GetBlockByIndex {
|
func NewGetBlockByIndex(indexStart uint32, count int16) *GetBlockByIndex {
|
||||||
return &GetBlockByIndex{
|
return &GetBlockByIndex{
|
||||||
IndexStart: indexStart,
|
IndexStart: indexStart,
|
||||||
|
|
|
@ -12,9 +12,9 @@ const (
|
||||||
MaxHashesCount = 500
|
MaxHashesCount = 500
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetBlocks contains fields and methods to be shared with the
|
// GetBlocks contains getblocks message payload fields.
|
||||||
type GetBlocks struct {
|
type GetBlocks struct {
|
||||||
// hash of latest block that node requests
|
// Hash of the latest block that node requests.
|
||||||
HashStart util.Uint256
|
HashStart util.Uint256
|
||||||
Count int16
|
Count int16
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,6 @@ func (p *GetBlocks) DecodeBinary(br *io.BinReader) {
|
||||||
if p.Count < -1 || p.Count == 0 {
|
if p.Count < -1 || p.Count == 0 {
|
||||||
br.Err = errors.New("invalid count")
|
br.Err = errors.New("invalid count")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeBinary implements Serializable interface.
|
// EncodeBinary implements Serializable interface.
|
||||||
|
|
|
@ -45,21 +45,21 @@ func TestNotaryRequestIsValid(t *testing.T) {
|
||||||
MainTransaction: mainTx,
|
MainTransaction: mainTx,
|
||||||
FallbackTransaction: &transaction.Transaction{
|
FallbackTransaction: &transaction.Transaction{
|
||||||
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
||||||
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 65}, make([]byte, 64, 64)...)}, {}},
|
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 65}, make([]byte, 64)...)}, {}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fallback tx: invalid dummy Notary witness (non-empty verification script))": {
|
"fallback tx: invalid dummy Notary witness (non-empty verification script))": {
|
||||||
MainTransaction: mainTx,
|
MainTransaction: mainTx,
|
||||||
FallbackTransaction: &transaction.Transaction{
|
FallbackTransaction: &transaction.Transaction{
|
||||||
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
||||||
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: make([]byte, 1, 1)}, {}},
|
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...), VerificationScript: make([]byte, 1)}, {}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fallback tx: missing NotValidBefore attribute": {
|
"fallback tx: missing NotValidBefore attribute": {
|
||||||
MainTransaction: mainTx,
|
MainTransaction: mainTx,
|
||||||
FallbackTransaction: &transaction.Transaction{
|
FallbackTransaction: &transaction.Transaction{
|
||||||
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
||||||
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fallback tx: invalid number of Conflicts attributes": {
|
"fallback tx: invalid number of Conflicts attributes": {
|
||||||
|
@ -67,7 +67,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
|
||||||
FallbackTransaction: &transaction.Transaction{
|
FallbackTransaction: &transaction.Transaction{
|
||||||
Attributes: []transaction.Attribute{{Type: transaction.NotValidBeforeT, Value: &transaction.NotValidBefore{Height: 123}}},
|
Attributes: []transaction.Attribute{{Type: transaction.NotValidBeforeT, Value: &transaction.NotValidBefore{Height: 123}}},
|
||||||
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
||||||
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fallback tx: does not conflicts with main tx": {
|
"fallback tx: does not conflicts with main tx": {
|
||||||
|
@ -78,7 +78,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
|
||||||
{Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: util.Uint256{}}},
|
{Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: util.Uint256{}}},
|
||||||
},
|
},
|
||||||
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
||||||
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fallback tx: missing NotaryAssisted attribute": {
|
"fallback tx: missing NotaryAssisted attribute": {
|
||||||
|
@ -89,7 +89,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
|
||||||
{Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: mainTx.Hash()}},
|
{Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: mainTx.Hash()}},
|
||||||
},
|
},
|
||||||
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
||||||
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fallback tx: non-zero NKeys": {
|
"fallback tx: non-zero NKeys": {
|
||||||
|
@ -101,7 +101,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
|
||||||
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}},
|
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}},
|
||||||
},
|
},
|
||||||
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
||||||
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"fallback tx: ValidUntilBlock mismatch": {
|
"fallback tx: ValidUntilBlock mismatch": {
|
||||||
|
@ -114,7 +114,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
|
||||||
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}},
|
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}},
|
||||||
},
|
},
|
||||||
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
||||||
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
|
||||||
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}},
|
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}},
|
||||||
},
|
},
|
||||||
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
||||||
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...), VerificationScript: make([]byte, 0)}, {}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
require.NoError(t, p.isValid())
|
require.NoError(t, p.isValid())
|
||||||
|
@ -164,7 +164,7 @@ func TestNotaryRequestBytesFromBytes(t *testing.T) {
|
||||||
},
|
},
|
||||||
Signers: []transaction.Signer{{Account: util.Uint160{1, 4, 7}}, {Account: util.Uint160{9, 8, 7}}},
|
Signers: []transaction.Signer{{Account: util.Uint160{1, 4, 7}}, {Account: util.Uint160{9, 8, 7}}},
|
||||||
Scripts: []transaction.Witness{
|
Scripts: []transaction.Witness{
|
||||||
{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: make([]byte, 0)},
|
{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...), VerificationScript: make([]byte, 0)},
|
||||||
{InvocationScript: []byte{1, 2, 3}, VerificationScript: []byte{1, 2, 3}}},
|
{InvocationScript: []byte{1, 2, 3}, VerificationScript: []byte{1, 2, 3}}},
|
||||||
}
|
}
|
||||||
_ = fallbackTx.Hash()
|
_ = fallbackTx.Hash()
|
||||||
|
|
|
@ -41,12 +41,10 @@ const (
|
||||||
var (
|
var (
|
||||||
errAlreadyConnected = errors.New("already connected")
|
errAlreadyConnected = errors.New("already connected")
|
||||||
errIdenticalID = errors.New("identical node id")
|
errIdenticalID = errors.New("identical node id")
|
||||||
errInvalidHandshake = errors.New("invalid handshake")
|
|
||||||
errInvalidNetwork = errors.New("invalid network")
|
errInvalidNetwork = errors.New("invalid network")
|
||||||
errMaxPeers = errors.New("max peers reached")
|
errMaxPeers = errors.New("max peers reached")
|
||||||
errServerShutdown = errors.New("server shutdown")
|
errServerShutdown = errors.New("server shutdown")
|
||||||
errInvalidInvType = errors.New("invalid inventory type")
|
errInvalidInvType = errors.New("invalid inventory type")
|
||||||
errInvalidHashStart = errors.New("invalid requested HashStart")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -411,7 +409,6 @@ func (s *Server) run() {
|
||||||
// because we have two goroutines sending signals here
|
// because we have two goroutines sending signals here
|
||||||
s.lock.Unlock()
|
s.lock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -864,7 +861,7 @@ func (s *Server) handleP2PNotaryRequestCmd(r *payload.P2PNotaryRequest) error {
|
||||||
}
|
}
|
||||||
// It's OK for it to fail for various reasons like request already existing
|
// It's OK for it to fail for various reasons like request already existing
|
||||||
// in the pool.
|
// in the pool.
|
||||||
s.RelayP2PNotaryRequest(r)
|
_ = s.RelayP2PNotaryRequest(r)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,6 @@ func TestServerRegisterPeer(t *testing.T) {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}, time.Second, time.Millisecond*50)
|
}, time.Second, time.Millisecond*50)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetBlocksByIndex(t *testing.T) {
|
func TestGetBlocksByIndex(t *testing.T) {
|
||||||
|
@ -535,7 +534,7 @@ func TestGetData(t *testing.T) {
|
||||||
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}},
|
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}},
|
||||||
},
|
},
|
||||||
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
|
||||||
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: make([]byte, 0)}, {InvocationScript: []byte{}, VerificationScript: []byte{}}},
|
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64)...), VerificationScript: make([]byte, 0)}, {InvocationScript: []byte{}, VerificationScript: []byte{}}},
|
||||||
}
|
}
|
||||||
fallbackTx.Size()
|
fallbackTx.Size()
|
||||||
fallbackTx.Hash()
|
fallbackTx.Hash()
|
||||||
|
|
|
@ -58,8 +58,6 @@ type TCPPeer struct {
|
||||||
p2pSendQ chan []byte
|
p2pSendQ chan []byte
|
||||||
hpSendQ chan []byte
|
hpSendQ chan []byte
|
||||||
|
|
||||||
wg sync.WaitGroup
|
|
||||||
|
|
||||||
// track outstanding getaddr requests.
|
// track outstanding getaddr requests.
|
||||||
getAddrSent atomic.Int32
|
getAddrSent atomic.Int32
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,7 @@ import (
|
||||||
const (
|
const (
|
||||||
defaultDialTimeout = 4 * time.Second
|
defaultDialTimeout = 4 * time.Second
|
||||||
defaultRequestTimeout = 4 * time.Second
|
defaultRequestTimeout = 4 * time.Second
|
||||||
defaultClientVersion = "2.0"
|
// Number of blocks after which cache is expired.
|
||||||
// number of blocks after which cache is expired
|
|
||||||
cacheTimeout = 100
|
cacheTimeout = 100
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -53,14 +52,14 @@ type Options struct {
|
||||||
RequestTimeout time.Duration
|
RequestTimeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache stores cache values for the RPC client methods
|
// cache stores cache values for the RPC client methods.
|
||||||
type cache struct {
|
type cache struct {
|
||||||
calculateValidUntilBlock calculateValidUntilBlockCache
|
calculateValidUntilBlock calculateValidUntilBlockCache
|
||||||
nativeHashes map[string]util.Uint160
|
nativeHashes map[string]util.Uint160
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculateValidUntilBlockCache stores cached number of validators and
|
// calculateValidUntilBlockCache stores cached number of validators and
|
||||||
// cache expiration value in blocks
|
// cache expiration value in blocks.
|
||||||
type calculateValidUntilBlockCache struct {
|
type calculateValidUntilBlockCache struct {
|
||||||
validatorsCount uint32
|
validatorsCount uint32
|
||||||
expiresAt uint32
|
expiresAt uint32
|
||||||
|
@ -92,8 +91,8 @@ func New(ctx context.Context, endpoint string, opts Options) (*Client, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(@antdm): Enable SSL.
|
// TODO(@antdm): Enable SSL.
|
||||||
if opts.Cert != "" && opts.Key != "" {
|
// if opts.Cert != "" && opts.Key != "" {
|
||||||
}
|
// }
|
||||||
|
|
||||||
cl := &Client{
|
cl := &Client{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
|
|
|
@ -463,7 +463,7 @@ func (c *Client) InvokeContractVerify(contract util.Uint160, params []smartcontr
|
||||||
return c.invokeSomething("invokecontractverify", p, signers, witnesses...)
|
return c.invokeSomething("invokecontractverify", p, signers, witnesses...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// invokeSomething is an inner wrapper for Invoke* functions
|
// invokeSomething is an inner wrapper for Invoke* functions.
|
||||||
func (c *Client) invokeSomething(method string, p request.RawParams, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) {
|
func (c *Client) invokeSomething(method string, p request.RawParams, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) {
|
||||||
var resp = new(result.Invoke)
|
var resp = new(result.Invoke)
|
||||||
if signers != nil {
|
if signers != nil {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue