mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-29 23:33:37 +00:00
Merge pull request #1281 from nspcc-dev/drop-go-1.12-and-fix-some-things
Drop go 1.12 and fix some things
This commit is contained in:
commit
c3c88a57cd
54 changed files with 235 additions and 280 deletions
|
@ -3,11 +3,6 @@ orbs:
|
||||||
codecov: codecov/codecov@1.0.5
|
codecov: codecov/codecov@1.0.5
|
||||||
|
|
||||||
executors:
|
executors:
|
||||||
go1_12:
|
|
||||||
docker:
|
|
||||||
- image: circleci/golang:1.12
|
|
||||||
environment:
|
|
||||||
GO111MODULE: "on"
|
|
||||||
go1_13:
|
go1_13:
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/golang:1.13
|
- image: circleci/golang:1.13
|
||||||
|
@ -54,16 +49,6 @@ jobs:
|
||||||
name: go-vet
|
name: go-vet
|
||||||
command: go vet ./...
|
command: go vet ./...
|
||||||
|
|
||||||
test_1_12:
|
|
||||||
working_directory: /go/src/github.com/nspcc-dev/neo-go
|
|
||||||
executor: go1_12
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- run: git submodule sync
|
|
||||||
- run: git submodule update --init
|
|
||||||
- gomod
|
|
||||||
- run: go test -v -race ./...
|
|
||||||
|
|
||||||
test_1_13:
|
test_1_13:
|
||||||
working_directory: /go/src/github.com/nspcc-dev/neo-go
|
working_directory: /go/src/github.com/nspcc-dev/neo-go
|
||||||
executor: go1_13
|
executor: go1_13
|
||||||
|
@ -100,7 +85,7 @@ jobs:
|
||||||
|
|
||||||
build_cli:
|
build_cli:
|
||||||
working_directory: /go/src/github.com/nspcc-dev/neo-go
|
working_directory: /go/src/github.com/nspcc-dev/neo-go
|
||||||
executor: go1_12
|
executor: go1_14
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- gomod
|
- gomod
|
||||||
|
@ -111,7 +96,7 @@ jobs:
|
||||||
|
|
||||||
build_image:
|
build_image:
|
||||||
working_directory: /go/src/github.com/nspcc-dev/neo-go
|
working_directory: /go/src/github.com/nspcc-dev/neo-go
|
||||||
executor: go1_12
|
executor: go1_14
|
||||||
docker:
|
docker:
|
||||||
- image: golang:1-alpine
|
- image: golang:1-alpine
|
||||||
steps:
|
steps:
|
||||||
|
@ -142,10 +127,6 @@ workflows:
|
||||||
filters:
|
filters:
|
||||||
tags:
|
tags:
|
||||||
only: v/[0-9]+\.[0-9]+\.[0-9]+/
|
only: v/[0-9]+\.[0-9]+\.[0-9]+/
|
||||||
- test_1_12:
|
|
||||||
filters:
|
|
||||||
tags:
|
|
||||||
only: v/[0-9]+\.[0-9]+\.[0-9]+/
|
|
||||||
- test_1_13:
|
- test_1_13:
|
||||||
filters:
|
filters:
|
||||||
tags:
|
tags:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
language: go
|
language: go
|
||||||
go:
|
go:
|
||||||
- 1.12.x
|
- 1.14.x
|
||||||
env:
|
env:
|
||||||
- GO111MODULE=on
|
- GO111MODULE=on
|
||||||
install:
|
install:
|
||||||
|
|
|
@ -19,7 +19,7 @@ RUN set -x \
|
||||||
&& export GO111MODULE=on \
|
&& export GO111MODULE=on \
|
||||||
&& export CGO_ENABLED=0 \
|
&& export CGO_ENABLED=0 \
|
||||||
&& export LDFLAGS="-X ${REPO}/pkg/config.Version=${VERSION}" \
|
&& export LDFLAGS="-X ${REPO}/pkg/config.Version=${VERSION}" \
|
||||||
&& go build -v -mod=vendor -ldflags "${LDFLAGS}" -o /go/bin/neo-go ./cli
|
&& go build -trimpath -v -mod=vendor -ldflags "${LDFLAGS}" -o /go/bin/neo-go ./cli
|
||||||
|
|
||||||
# Executable image
|
# Executable image
|
||||||
FROM alpine
|
FROM alpine
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -26,7 +26,7 @@ build: deps
|
||||||
@set -x \
|
@set -x \
|
||||||
&& export GOGC=off \
|
&& export GOGC=off \
|
||||||
&& export CGO_ENABLED=0 \
|
&& export CGO_ENABLED=0 \
|
||||||
&& go build -v -mod=vendor -ldflags $(BUILD_FLAGS) -o ${BINARY} ./cli/main.go
|
&& go build -trimpath -v -mod=vendor -ldflags $(BUILD_FLAGS) -o ${BINARY} ./cli/main.go
|
||||||
|
|
||||||
neo-go.service: neo-go.service.template
|
neo-go.service: neo-go.service.template
|
||||||
@sed -r -e 's_BINDIR_$(BINDIR)_' -e 's_UNITWORKDIR_$(UNITWORKDIR)_' -e 's_SYSCONFIGDIR_$(SYSCONFIGDIR)_' $< >$@
|
@sed -r -e 's_BINDIR_$(BINDIR)_' -e 's_UNITWORKDIR_$(UNITWORKDIR)_' -e 's_SYSCONFIGDIR_$(SYSCONFIGDIR)_' $< >$@
|
||||||
|
|
|
@ -36,7 +36,7 @@ Neo 3 code (0.90.0 being compatible with Neo 3 preview2).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Go: 1.12+
|
Go: 1.13+
|
||||||
|
|
||||||
Install dependencies.
|
Install dependencies.
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/network"
|
"github.com/nspcc-dev/neo-go/pkg/network"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/network/metrics"
|
"github.com/nspcc-dev/neo-go/pkg/network/metrics"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpc/server"
|
"github.com/nspcc-dev/neo-go/pkg/rpc/server"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
|
@ -198,7 +197,7 @@ func dumpDB(ctx *cli.Context) error {
|
||||||
bh := chain.GetHeaderHash(int(i))
|
bh := chain.GetHeaderHash(int(i))
|
||||||
b, err := chain.GetBlock(bh)
|
b, err := chain.GetBlock(bh)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to get block %d: %s", i, err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to get block %d: %w", i, err), 1)
|
||||||
}
|
}
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
b.EncodeBinary(buf.BinWriter)
|
b.EncodeBinary(buf.BinWriter)
|
||||||
|
@ -296,7 +295,7 @@ func restoreDB(ctx *cli.Context) error {
|
||||||
} else {
|
} else {
|
||||||
err = chain.AddBlock(block)
|
err = chain.AddBlock(block)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to add block %d: %s", i, err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to add block %d: %w", i, err), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if dumpDir != "" {
|
if dumpDir != "" {
|
||||||
|
@ -309,7 +308,7 @@ func restoreDB(ctx *cli.Context) error {
|
||||||
lastIndex = block.Index
|
lastIndex = block.Index
|
||||||
if block.Index%1000 == 0 {
|
if block.Index%1000 == 0 {
|
||||||
if err := dump.tryPersist(dumpDir, block.Index); err != nil {
|
if err := dump.tryPersist(dumpDir, block.Index); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't dump storage to file: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't dump storage to file: %w", err), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -350,7 +349,7 @@ func startServer(ctx *cli.Context) error {
|
||||||
|
|
||||||
serv, err := network.NewServer(serverConfig, chain, log)
|
serv, err := network.NewServer(serverConfig, chain, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to create network server: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to create network server: %w", err), 1)
|
||||||
}
|
}
|
||||||
rpcServer := server.New(chain, cfg.ApplicationConfiguration.RPC, serv, log)
|
rpcServer := server.New(chain, cfg.ApplicationConfiguration.RPC, serv, log)
|
||||||
errChan := make(chan error)
|
errChan := make(chan error)
|
||||||
|
@ -367,13 +366,13 @@ Main:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case err := <-errChan:
|
case err := <-errChan:
|
||||||
shutdownErr = errors.Wrap(err, "Error encountered by server")
|
shutdownErr = fmt.Errorf("server error: %w", err)
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
case <-grace.Done():
|
case <-grace.Done():
|
||||||
serv.Shutdown()
|
serv.Shutdown()
|
||||||
if serverErr := rpcServer.Shutdown(); serverErr != nil {
|
if serverErr := rpcServer.Shutdown(); serverErr != nil {
|
||||||
shutdownErr = errors.Wrap(serverErr, "Error encountered whilst shutting down server")
|
shutdownErr = fmt.Errorf("error on shutdown: %w", serverErr)
|
||||||
}
|
}
|
||||||
prometheus.ShutDown()
|
prometheus.ShutDown()
|
||||||
pprof.ShutDown()
|
pprof.ShutDown()
|
||||||
|
@ -411,12 +410,12 @@ func configureAddresses(cfg config.ApplicationConfiguration) {
|
||||||
func initBlockChain(cfg config.Config, log *zap.Logger) (*core.Blockchain, error) {
|
func initBlockChain(cfg config.Config, log *zap.Logger) (*core.Blockchain, error) {
|
||||||
store, err := storage.NewStore(cfg.ApplicationConfiguration.DBConfiguration)
|
store, err := storage.NewStore(cfg.ApplicationConfiguration.DBConfiguration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, cli.NewExitError(fmt.Errorf("could not initialize storage: %s", err), 1)
|
return nil, cli.NewExitError(fmt.Errorf("could not initialize storage: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
chain, err := core.NewBlockchain(store, cfg.ProtocolConfiguration, log)
|
chain, err := core.NewBlockchain(store, cfg.ProtocolConfiguration, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, cli.NewExitError(fmt.Errorf("could not initialize blockchain: %s", err), 1)
|
return nil, cli.NewExitError(fmt.Errorf("could not initialize blockchain: %w", err), 1)
|
||||||
}
|
}
|
||||||
return chain, nil
|
return chain, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
@ -25,7 +26,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
@ -411,7 +411,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
||||||
}
|
}
|
||||||
script, err := util.Uint160DecodeStringLE(args[0])
|
script, err := util.Uint160DecodeStringLE(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("incorrect script hash: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("incorrect script hash: %w", err), 1)
|
||||||
}
|
}
|
||||||
if len(args) <= 1 {
|
if len(args) <= 1 {
|
||||||
return cli.NewExitError(errNoMethod, 1)
|
return cli.NewExitError(errNoMethod, 1)
|
||||||
|
@ -427,7 +427,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
||||||
}
|
}
|
||||||
param, err := smartcontract.NewParameterFromString(s)
|
param, err := smartcontract.NewParameterFromString(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to parse argument #%d: %v", k+paramsStart+1, err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to parse argument #%d: %w", k+paramsStart+1, err), 1)
|
||||||
}
|
}
|
||||||
params = append(params, *param)
|
params = append(params, *param)
|
||||||
}
|
}
|
||||||
|
@ -437,7 +437,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
||||||
for i, c := range args[cosignersStart:] {
|
for i, c := range args[cosignersStart:] {
|
||||||
cosigner, err := parseCosigner(c)
|
cosigner, err := parseCosigner(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to parse cosigner #%d: %v", i+1, err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to parse cosigner #%d: %w", i+1, err), 1)
|
||||||
}
|
}
|
||||||
cosigners = append(cosigners, cosigner)
|
cosigners = append(cosigners, cosigner)
|
||||||
}
|
}
|
||||||
|
@ -468,11 +468,11 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
||||||
}
|
}
|
||||||
script, err := hex.DecodeString(resp.Script)
|
script, err := hex.DecodeString(resp.Script)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("bad script returned from the RPC node: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("bad script returned from the RPC node: %w", err), 1)
|
||||||
}
|
}
|
||||||
txHash, err := c.SignAndPushInvocationTx(script, acc, resp.GasConsumed, gas, cosigners)
|
txHash, err := c.SignAndPushInvocationTx(script, acc, resp.GasConsumed, gas, cosigners)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %w", err), 1)
|
||||||
}
|
}
|
||||||
fmt.Printf("Sent invocation transaction %s\n", txHash.StringLE())
|
fmt.Printf("Sent invocation transaction %s\n", txHash.StringLE())
|
||||||
} else {
|
} else {
|
||||||
|
@ -499,7 +499,7 @@ func testInvokeScript(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
nefFile, err := nef.FileFromBytes(b)
|
nefFile, err := nef.FileFromBytes(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(errors.Wrapf(err, "failed to restore .nef file"), 1)
|
return cli.NewExitError(fmt.Errorf("failed to restore .nef file: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
args := ctx.Args()
|
args := ctx.Args()
|
||||||
|
@ -508,7 +508,7 @@ func testInvokeScript(ctx *cli.Context) error {
|
||||||
for i, c := range args[:] {
|
for i, c := range args[:] {
|
||||||
cosigner, err := parseCosigner(c)
|
cosigner, err := parseCosigner(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to parse signer #%d: %v", i+1, err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to parse signer #%d: %w", i+1, err), 1)
|
||||||
}
|
}
|
||||||
signers = append(signers, cosigner)
|
signers = append(signers, cosigner)
|
||||||
}
|
}
|
||||||
|
@ -570,12 +570,12 @@ func inspect(ctx *cli.Context) error {
|
||||||
if compile {
|
if compile {
|
||||||
b, err = compiler.Compile(bytes.NewReader(b))
|
b, err = compiler.Compile(bytes.NewReader(b))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(errors.Wrap(err, "failed to compile"), 1)
|
return cli.NewExitError(fmt.Errorf("failed to compile: %w", err), 1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nefFile, err := nef.FileFromBytes(b)
|
nefFile, err := nef.FileFromBytes(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(errors.Wrapf(err, "failed to restore .nef file"), 1)
|
return cli.NewExitError(fmt.Errorf("failed to restore .nef file: %w", err), 1)
|
||||||
}
|
}
|
||||||
b = nefFile.Script
|
b = nefFile.Script
|
||||||
}
|
}
|
||||||
|
@ -645,17 +645,17 @@ func contractDeploy(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
nefFile, err := nef.FileFromBytes(f)
|
nefFile, err := nef.FileFromBytes(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(errors.Wrapf(err, "failed to restore .nef file"), 1)
|
return cli.NewExitError(fmt.Errorf("failed to restore .nef file: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
manifestBytes, err := ioutil.ReadFile(manifestFile)
|
manifestBytes, err := ioutil.ReadFile(manifestFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(errors.Wrapf(err, "failed to read manifest file"), 1)
|
return cli.NewExitError(fmt.Errorf("failed to read manifest file: %w", err), 1)
|
||||||
}
|
}
|
||||||
m := &manifest.Manifest{}
|
m := &manifest.Manifest{}
|
||||||
err = json.Unmarshal(manifestBytes, m)
|
err = json.Unmarshal(manifestBytes, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(errors.Wrapf(err, "failed to restore manifest file"), 1)
|
return cli.NewExitError(fmt.Errorf("failed to restore manifest file: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
gctx, cancel := options.GetTimeoutContext(ctx)
|
gctx, cancel := options.GetTimeoutContext(ctx)
|
||||||
|
@ -668,17 +668,17 @@ func contractDeploy(ctx *cli.Context) error {
|
||||||
|
|
||||||
txScript, err := request.CreateDeploymentScript(nefFile.Script, m)
|
txScript, err := request.CreateDeploymentScript(nefFile.Script, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to create deployment script: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to create deployment script: %w", err), 1)
|
||||||
}
|
}
|
||||||
// It doesn't require any signers.
|
// It doesn't require any signers.
|
||||||
invRes, err := c.InvokeScript(txScript, nil)
|
invRes, err := c.InvokeScript(txScript, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to test-invoke deployment script: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to test-invoke deployment script: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
txHash, err := c.SignAndPushInvocationTx(txScript, acc, invRes.GasConsumed, gas, nil)
|
txHash, err := c.SignAndPushInvocationTx(txScript, acc, invRes.GasConsumed, gas, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %w", err), 1)
|
||||||
}
|
}
|
||||||
fmt.Printf("Sent deployment transaction %s for contract %s\n", txHash.StringLE(), nefFile.Header.ScriptHash.StringLE())
|
fmt.Printf("Sent deployment transaction %s for contract %s\n", txHash.StringLE(), nefFile.Header.ScriptHash.StringLE())
|
||||||
return nil
|
return nil
|
||||||
|
@ -693,7 +693,7 @@ func parseContractConfig(confFile string) (ProjectConfig, error) {
|
||||||
|
|
||||||
err = yaml.Unmarshal(confBytes, &conf)
|
err = yaml.Unmarshal(confBytes, &conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return conf, cli.NewExitError(fmt.Errorf("bad config: %v", err), 1)
|
return conf, cli.NewExitError(fmt.Errorf("bad config: %w", err), 1)
|
||||||
}
|
}
|
||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func signMultisig(ctx *cli.Context) error {
|
||||||
addr := ctx.String("addr")
|
addr := ctx.String("addr")
|
||||||
sh, err := address.StringToUint160(addr)
|
sh, err := address.StringToUint160(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("invalid address: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("invalid address: %w", err), 1)
|
||||||
}
|
}
|
||||||
acc := wall.GetAccount(sh)
|
acc := wall.GetAccount(sh)
|
||||||
if acc == nil {
|
if acc == nil {
|
||||||
|
@ -65,13 +65,13 @@ func signMultisig(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
} else if err := acc.Decrypt(pass); err != nil {
|
} else if err := acc.Decrypt(pass); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't unlock an account: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't unlock an account: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
priv := acc.PrivateKey()
|
priv := acc.PrivateKey()
|
||||||
sign := priv.Sign(tx.GetSignedPart())
|
sign := priv.Sign(tx.GetSignedPart())
|
||||||
if err := c.AddSignature(acc.Contract, priv.PublicKey(), sign); err != nil {
|
if err := c.AddSignature(acc.Contract, priv.PublicKey(), sign); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't add signature: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't add signature: %w", err), 1)
|
||||||
} else if err := writeParameterContext(c, ctx.String("out")); err != nil {
|
} else if err := writeParameterContext(c, ctx.String("out")); err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
|
@ -104,21 +104,21 @@ func signMultisig(ctx *cli.Context) error {
|
||||||
func readParameterContext(filename string) (*context.ParameterContext, error) {
|
func readParameterContext(filename string) (*context.ParameterContext, error) {
|
||||||
data, err := ioutil.ReadFile(filename)
|
data, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't read input file: %v", err)
|
return nil, fmt.Errorf("can't read input file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c := new(context.ParameterContext)
|
c := new(context.ParameterContext)
|
||||||
if err := json.Unmarshal(data, c); err != nil {
|
if err := json.Unmarshal(data, c); err != nil {
|
||||||
return nil, fmt.Errorf("can't parse transaction: %v", err)
|
return nil, fmt.Errorf("can't parse transaction: %w", err)
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeParameterContext(c *context.ParameterContext, filename string) error {
|
func writeParameterContext(c *context.ParameterContext, filename string) error {
|
||||||
if data, err := json.Marshal(c); err != nil {
|
if data, err := json.Marshal(c); err != nil {
|
||||||
return fmt.Errorf("can't marshal transaction: %v", err)
|
return fmt.Errorf("can't marshal transaction: %w", err)
|
||||||
} else if err := ioutil.WriteFile(filename, data, 0644); err != nil {
|
} else if err := ioutil.WriteFile(filename, data, 0644); err != nil {
|
||||||
return fmt.Errorf("can't write transaction to file: %v", err)
|
return fmt.Errorf("can't write transaction to file: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ func getNEP5Balance(ctx *cli.Context) error {
|
||||||
addr := ctx.String("addr")
|
addr := ctx.String("addr")
|
||||||
addrHash, err := address.StringToUint160(addr)
|
addrHash, err := address.StringToUint160(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("invalid address: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("invalid address: %w", err), 1)
|
||||||
}
|
}
|
||||||
acc := wall.GetAccount(addrHash)
|
acc := wall.GetAccount(addrHash)
|
||||||
if acc == nil {
|
if acc == nil {
|
||||||
|
@ -242,7 +242,7 @@ func importNEP5Token(ctx *cli.Context) error {
|
||||||
|
|
||||||
tokenHash, err := util.Uint160DecodeStringLE(ctx.String("token"))
|
tokenHash, err := util.Uint160DecodeStringLE(ctx.String("token"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("invalid token contract hash: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("invalid token contract hash: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, t := range wall.Extra.Tokens {
|
for _, t := range wall.Extra.Tokens {
|
||||||
|
@ -262,7 +262,7 @@ func importNEP5Token(ctx *cli.Context) error {
|
||||||
|
|
||||||
tok, err := c.NEP5TokenInfo(tokenHash)
|
tok, err := c.NEP5TokenInfo(tokenHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't receive token info: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't receive token info: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
wall.AddToken(tok)
|
wall.AddToken(tok)
|
||||||
|
@ -327,9 +327,9 @@ func removeNEP5Token(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := wall.RemoveToken(token.Hash); err != nil {
|
if err := wall.RemoveToken(token.Hash); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't remove token: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't remove token: %w", err), 1)
|
||||||
} else if err := wall.Save(); err != nil {
|
} else if err := wall.Save(); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("error while saving wallet: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("error while saving wallet: %w", err), 1)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -385,7 +385,7 @@ func multiTransferNEP5(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
amount, err := util.FixedNFromString(ss[2], int(token.Decimals))
|
amount, err := util.FixedNFromString(ss[2], int(token.Decimals))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("invalid amount: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("invalid amount: %w", err), 1)
|
||||||
}
|
}
|
||||||
recepients = append(recepients, client.TransferTarget{
|
recepients = append(recepients, client.TransferTarget{
|
||||||
Token: token.Hash,
|
Token: token.Hash,
|
||||||
|
@ -432,7 +432,7 @@ func transferNEP5(ctx *cli.Context) error {
|
||||||
|
|
||||||
amount, err := util.FixedNFromString(ctx.String("amount"), int(token.Decimals))
|
amount, err := util.FixedNFromString(ctx.String("amount"), int(token.Decimals))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("invalid amount: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("invalid amount: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return signAndSendTransfer(ctx, c, acc, []client.TransferTarget{{
|
return signAndSendTransfer(ctx, c, acc, []client.TransferTarget{{
|
||||||
|
@ -464,11 +464,11 @@ func signAndSendTransfer(ctx *cli.Context, c *client.Client, acc *wallet.Account
|
||||||
sign := priv.Sign(tx.GetSignedPart())
|
sign := priv.Sign(tx.GetSignedPart())
|
||||||
scCtx := context.NewParameterContext("Neo.Core.ContractTransaction", tx)
|
scCtx := context.NewParameterContext("Neo.Core.ContractTransaction", tx)
|
||||||
if err := scCtx.AddSignature(acc.Contract, pub, sign); err != nil {
|
if err := scCtx.AddSignature(acc.Contract, pub, sign); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't add signature: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't add signature: %w", err), 1)
|
||||||
} else if data, err := json.Marshal(scCtx); err != nil {
|
} else if data, err := json.Marshal(scCtx); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't marshal tx to JSON: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't marshal tx to JSON: %w", err), 1)
|
||||||
} else if err := ioutil.WriteFile(outFile, data, 0644); err != nil {
|
} else if err := ioutil.WriteFile(outFile, data, 0644); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't write tx to file: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't write tx to file: %w", err), 1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_ = acc.SignTx(tx)
|
_ = acc.SignTx(tx)
|
||||||
|
|
|
@ -284,7 +284,7 @@ func convertWallet(ctx *cli.Context) error {
|
||||||
address.Prefix = address.NEO3Prefix
|
address.Prefix = address.NEO3Prefix
|
||||||
newAcc, err := wallet.NewAccountFromWIF(acc.PrivateKey().WIF())
|
newAcc, err := wallet.NewAccountFromWIF(acc.PrivateKey().WIF())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't convert account: %v", err), -1)
|
return cli.NewExitError(fmt.Errorf("can't convert account: %w", err), -1)
|
||||||
}
|
}
|
||||||
newAcc.Address = address.Uint160ToString(acc.Contract.ScriptHash())
|
newAcc.Address = address.Uint160ToString(acc.Contract.ScriptHash())
|
||||||
newAcc.Contract = acc.Contract
|
newAcc.Contract = acc.Contract
|
||||||
|
@ -292,7 +292,7 @@ func convertWallet(ctx *cli.Context) error {
|
||||||
newAcc.Label = acc.Label
|
newAcc.Label = acc.Label
|
||||||
newAcc.Locked = acc.Locked
|
newAcc.Locked = acc.Locked
|
||||||
if err := newAcc.Encrypt(pass); err != nil {
|
if err := newAcc.Encrypt(pass); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't encrypt converted account: %v", err), -1)
|
return cli.NewExitError(fmt.Errorf("can't encrypt converted account: %w", err), -1)
|
||||||
}
|
}
|
||||||
newWallet.AddAccount(newAcc)
|
newWallet.AddAccount(newAcc)
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ func exportKeys(ctx *cli.Context) error {
|
||||||
addr = ctx.Args().First()
|
addr = ctx.Args().First()
|
||||||
_, err := address.StringToUint160(addr)
|
_, err := address.StringToUint160(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't parse address: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("can't parse address: %w", err), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ func importMultisig(ctx *cli.Context) error {
|
||||||
for i := range args {
|
for i := range args {
|
||||||
pubs[i], err = keys.NewPublicKeyFromString(args[i])
|
pubs[i], err = keys.NewPublicKeyFromString(args[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("can't decode public key %d: %v", i, err), 1)
|
return cli.NewExitError(fmt.Errorf("can't decode public key %d: %w", i, err), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,9 +468,9 @@ func removeAccount(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := wall.RemoveAccount(acc.Address); err != nil {
|
if err := wall.RemoveAccount(acc.Address); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("error on remove: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("error on remove: %w", err), 1)
|
||||||
} else if err := wall.Save(); err != nil {
|
} else if err := wall.Save(); err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("error while saving wallet: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("error while saving wallet: %w", err), 1)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,4 +14,25 @@ func example(test int) (num int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
In the above function we have used a named return paramter, which allows you to include a simple return statement without the variables you are returning. This practice can cause confusion when functions become large or the logic becomes complex, so these should be avoided.
|
In the above function we have used a named return paramter, which allows you to include a simple return statement without the variables you are returning. This practice can cause confusion when functions become large or the logic becomes complex, so these should be avoided.
|
||||||
|
|
||||||
|
## Use error wrapping
|
||||||
|
|
||||||
|
Bad:
|
||||||
|
```
|
||||||
|
err = SomeAPI()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("something bad happened: %v", err)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Good:
|
||||||
|
```
|
||||||
|
err = SomeAPI()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("something bad happened: %w", err)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Error wrapping allows `errors.Is` and `errors.As` usage in upper layer
|
||||||
|
functions which might be useful.
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -13,7 +13,6 @@ require (
|
||||||
github.com/nspcc-dev/dbft v0.0.0-20200711144034-c526ccc6f570
|
github.com/nspcc-dev/dbft v0.0.0-20200711144034-c526ccc6f570
|
||||||
github.com/nspcc-dev/rfc6979 v0.2.0
|
github.com/nspcc-dev/rfc6979 v0.2.0
|
||||||
github.com/pierrec/lz4 v2.5.2+incompatible
|
github.com/pierrec/lz4 v2.5.2+incompatible
|
||||||
github.com/pkg/errors v0.8.1
|
|
||||||
github.com/prometheus/client_golang v1.2.1
|
github.com/prometheus/client_golang v1.2.1
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
github.com/syndtr/goleveldb v0.0.0-20180307113352-169b1b37be73
|
github.com/syndtr/goleveldb v0.0.0-20180307113352-169b1b37be73
|
||||||
|
@ -28,4 +27,4 @@ require (
|
||||||
gopkg.in/abiosoft/ishell.v2 v2.0.0
|
gopkg.in/abiosoft/ishell.v2 v2.0.0
|
||||||
)
|
)
|
||||||
|
|
||||||
go 1.12
|
go 1.13
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"golang.org/x/tools/go/loader"
|
"golang.org/x/tools/go/loader"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -141,15 +140,15 @@ func CompileAndSave(src string, o *Options) ([]byte, error) {
|
||||||
}
|
}
|
||||||
b, di, err := CompileWithDebugInfo(bytes.NewReader(b))
|
b, di, err := CompileWithDebugInfo(bytes.NewReader(b))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error while trying to compile smart contract file: %v", err)
|
return nil, fmt.Errorf("error while trying to compile smart contract file: %w", err)
|
||||||
}
|
}
|
||||||
f, err := nef.NewFile(b)
|
f, err := nef.NewFile(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error while trying to create .nef file: %v", err)
|
return nil, fmt.Errorf("error while trying to create .nef file: %w", err)
|
||||||
}
|
}
|
||||||
bytes, err := f.Bytes()
|
bytes, err := f.Bytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error while serializing .nef file: %v", err)
|
return nil, fmt.Errorf("error while serializing .nef file: %w", err)
|
||||||
}
|
}
|
||||||
out := fmt.Sprintf("%s.%s", o.Outfile, o.Ext)
|
out := fmt.Sprintf("%s.%s", o.Outfile, o.Ext)
|
||||||
err = ioutil.WriteFile(out, bytes, os.ModePerm)
|
err = ioutil.WriteFile(out, bytes, os.ModePerm)
|
||||||
|
@ -179,11 +178,11 @@ func CompileAndSave(src string, o *Options) ([]byte, error) {
|
||||||
if o.ManifestFile != "" {
|
if o.ManifestFile != "" {
|
||||||
m, err := di.ConvertToManifest(o.ContractFeatures, o.ContractSupportedStandards...)
|
m, err := di.ConvertToManifest(o.ContractFeatures, o.ContractSupportedStandards...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return b, errors.Wrap(err, "failed to convert debug info to manifest")
|
return b, fmt.Errorf("failed to convert debug info to manifest: %w", err)
|
||||||
}
|
}
|
||||||
mData, err := json.Marshal(m)
|
mData, err := json.Marshal(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return b, errors.Wrap(err, "failed to marshal manifest")
|
return b, fmt.Errorf("failed to marshal manifest to JSON: %w", err)
|
||||||
}
|
}
|
||||||
return b, ioutil.WriteFile(o.ManifestFile, mData, os.ModePerm)
|
return b, ioutil.WriteFile(o.ManifestFile, mData, os.ModePerm)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
|
|
||||||
"github.com/go-yaml/yaml"
|
"github.com/go-yaml/yaml"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const userAgentFormat = "/NEO-GO:%s/"
|
const userAgentFormat = "/NEO-GO:%s/"
|
||||||
|
@ -37,12 +36,12 @@ func Load(path string, netMode netmode.Magic) (Config, error) {
|
||||||
// LoadFile loads config from the provided path.
|
// LoadFile loads config from the provided path.
|
||||||
func LoadFile(configPath string) (Config, error) {
|
func LoadFile(configPath string) (Config, error) {
|
||||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||||
return Config{}, errors.Wrap(err, "Unable to load config")
|
return Config{}, fmt.Errorf("config '%s' doesn't exist", configPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
configData, err := ioutil.ReadFile(configPath)
|
configData, err := ioutil.ReadFile(configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Config{}, errors.Wrap(err, "Unable to read config")
|
return Config{}, fmt.Errorf("unable to read config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config := Config{
|
config := Config{
|
||||||
|
@ -54,7 +53,7 @@ func LoadFile(configPath string) (Config, error) {
|
||||||
|
|
||||||
err = yaml.Unmarshal(configData, &config)
|
err = yaml.Unmarshal(configData, &config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Config{}, errors.Wrap(err, "Problem unmarshaling config json data")
|
return Config{}, fmt.Errorf("failed to unmarshal config YAML: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return config, nil
|
return config, nil
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft/payload"
|
||||||
|
@ -14,7 +15,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -306,7 +306,7 @@ func (m *message) DecodeBinary(r *io.BinReader) {
|
||||||
case recoveryMessageType:
|
case recoveryMessageType:
|
||||||
m.payload = new(recoveryMessage)
|
m.payload = new(recoveryMessage)
|
||||||
default:
|
default:
|
||||||
r.Err = errors.Errorf("invalid type: 0x%02x", byte(m.Type))
|
r.Err = fmt.Errorf("invalid type: 0x%02x", byte(m.Type))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
m.payload.DecodeBinary(r)
|
m.payload.DecodeBinary(r)
|
||||||
|
@ -338,7 +338,7 @@ func (p *Payload) decodeData() error {
|
||||||
br := io.NewBinReaderFromBuf(p.data)
|
br := io.NewBinReaderFromBuf(p.data)
|
||||||
m.DecodeBinary(br)
|
m.DecodeBinary(br)
|
||||||
if br.Err != nil {
|
if br.Err != nil {
|
||||||
return errors.Wrap(br.Err, "cannot decode data into message")
|
return fmt.Errorf("can't decode message: %w", br.Err)
|
||||||
}
|
}
|
||||||
p.message = m
|
p.message = m
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/nspcc-dev/dbft/crypto"
|
"github.com/nspcc-dev/dbft/crypto"
|
||||||
"github.com/nspcc-dev/dbft/payload"
|
"github.com/nspcc-dev/dbft/payload"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
@ -27,7 +27,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -223,7 +222,7 @@ func (bc *Blockchain) init() error {
|
||||||
bc.blockHeight = bHeight
|
bc.blockHeight = bHeight
|
||||||
bc.persistedHeight = bHeight
|
bc.persistedHeight = bHeight
|
||||||
if err = bc.dao.InitMPT(bHeight); err != nil {
|
if err = bc.dao.InitMPT(bHeight); err != nil {
|
||||||
return errors.Wrapf(err, "can't init MPT at height %d", bHeight)
|
return fmt.Errorf("can't init MPT at height %d: %w", bHeight, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hashes, err := bc.dao.GetHeaderHashes()
|
hashes, err := bc.dao.GetHeaderHashes()
|
||||||
|
@ -263,7 +262,7 @@ func (bc *Blockchain) init() error {
|
||||||
for hash != targetHash {
|
for hash != targetHash {
|
||||||
header, err := bc.GetHeader(hash)
|
header, err := bc.GetHeader(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not get header %s: %s", hash, err)
|
return fmt.Errorf("could not get header %s: %w", hash, err)
|
||||||
}
|
}
|
||||||
headers = append(headers, header)
|
headers = append(headers, header)
|
||||||
hash = header.PrevHash
|
hash = header.PrevHash
|
||||||
|
@ -420,7 +419,7 @@ func (bc *Blockchain) AddBlock(block *block.Block) error {
|
||||||
|
|
||||||
expectedHeight := bc.BlockHeight() + 1
|
expectedHeight := bc.BlockHeight() + 1
|
||||||
if expectedHeight != block.Index {
|
if expectedHeight != block.Index {
|
||||||
return ErrInvalidBlockIndex
|
return fmt.Errorf("expected %d, got %d: %w", expectedHeight, block.Index, ErrInvalidBlockIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
headerLen := bc.headerListLen()
|
headerLen := bc.headerListLen()
|
||||||
|
@ -433,13 +432,13 @@ func (bc *Blockchain) AddBlock(block *block.Block) error {
|
||||||
if bc.config.VerifyBlocks {
|
if bc.config.VerifyBlocks {
|
||||||
err := block.Verify()
|
err := block.Verify()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("block %s is invalid: %s", block.Hash().StringLE(), err)
|
return fmt.Errorf("block %s is invalid: %w", block.Hash().StringLE(), err)
|
||||||
}
|
}
|
||||||
if bc.config.VerifyTransactions {
|
if bc.config.VerifyTransactions {
|
||||||
for _, tx := range block.Transactions {
|
for _, tx := range block.Transactions {
|
||||||
err := bc.VerifyTx(tx, block)
|
err := bc.VerifyTx(tx, block)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("transaction %s failed to verify: %s", tx.Hash().StringLE(), err)
|
return fmt.Errorf("transaction %s failed to verify: %w", tx.Hash().StringLE(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,7 +477,7 @@ func (bc *Blockchain) addHeaders(verify bool, headers ...*block.Header) (err err
|
||||||
// Verify that the chain of the headers is consistent.
|
// Verify that the chain of the headers is consistent.
|
||||||
var lastHeader *block.Header
|
var lastHeader *block.Header
|
||||||
if lastHeader, err = bc.GetHeader(headers[0].PrevHash); err != nil {
|
if lastHeader, err = bc.GetHeader(headers[0].PrevHash); err != nil {
|
||||||
return fmt.Errorf("previous header was not found: %v", err)
|
return fmt.Errorf("previous header was not found: %w", err)
|
||||||
}
|
}
|
||||||
for _, h := range headers {
|
for _, h := range headers {
|
||||||
if err = bc.verifyHeader(h, lastHeader); err != nil {
|
if err = bc.verifyHeader(h, lastHeader); err != nil {
|
||||||
|
@ -579,9 +578,9 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
v.LoadScriptWithFlags(bc.contracts.GetPersistScript(), smartcontract.AllowModifyStates|smartcontract.AllowCall)
|
v.LoadScriptWithFlags(bc.contracts.GetPersistScript(), smartcontract.AllowModifyStates|smartcontract.AllowCall)
|
||||||
v.SetPriceGetter(getPrice)
|
v.SetPriceGetter(getPrice)
|
||||||
if err := v.Run(); err != nil {
|
if err := v.Run(); err != nil {
|
||||||
return errors.Wrap(err, "can't persist native contracts")
|
return fmt.Errorf("onPersist run failed: %w", err)
|
||||||
} else if _, err := systemInterop.DAO.Persist(); err != nil {
|
} else if _, err := systemInterop.DAO.Persist(); err != nil {
|
||||||
return errors.Wrap(err, "can't persist `onPersist` changes")
|
return fmt.Errorf("can't save onPersist changes: %w", err)
|
||||||
}
|
}
|
||||||
for i := range systemInterop.Notifications {
|
for i := range systemInterop.Notifications {
|
||||||
bc.handleNotification(&systemInterop.Notifications[i], cache, block, block.Hash())
|
bc.handleNotification(&systemInterop.Notifications[i], cache, block, block.Hash())
|
||||||
|
@ -597,7 +596,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
appExecResults = append(appExecResults, aer)
|
appExecResults = append(appExecResults, aer)
|
||||||
err := cache.PutAppExecResult(aer)
|
err := cache.PutAppExecResult(aer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to Store notifications")
|
return fmt.Errorf("failed to store onPersist exec result: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,7 +615,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
if !v.HasFailed() {
|
if !v.HasFailed() {
|
||||||
_, err := systemInterop.DAO.Persist()
|
_, err := systemInterop.DAO.Persist()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to persist invocation results")
|
return fmt.Errorf("failed to persist invocation results: %w", err)
|
||||||
}
|
}
|
||||||
for i := range systemInterop.Notifications {
|
for i := range systemInterop.Notifications {
|
||||||
bc.handleNotification(&systemInterop.Notifications[i], cache, block, tx.Hash())
|
bc.handleNotification(&systemInterop.Notifications[i], cache, block, tx.Hash())
|
||||||
|
@ -638,7 +637,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
appExecResults = append(appExecResults, aer)
|
appExecResults = append(appExecResults, aer)
|
||||||
err = cache.PutAppExecResult(aer)
|
err = cache.PutAppExecResult(aer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to Store notifications")
|
return fmt.Errorf("failed to store tx exec result: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,7 +646,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
if block.Index > 0 {
|
if block.Index > 0 {
|
||||||
prev, err := bc.dao.GetStateRoot(block.Index - 1)
|
prev, err := bc.dao.GetStateRoot(block.Index - 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.WithMessagef(err, "can't get previous state root")
|
return fmt.Errorf("can't get previous state root: %w", err)
|
||||||
}
|
}
|
||||||
prevHash = hash.DoubleSha256(prev.GetSignedPart())
|
prevHash = hash.DoubleSha256(prev.GetSignedPart())
|
||||||
}
|
}
|
||||||
|
@ -1204,41 +1203,26 @@ func (bc *Blockchain) verifyHeader(currHeader, prevHeader *block.Header) error {
|
||||||
func (bc *Blockchain) verifyTx(t *transaction.Transaction, block *block.Block) error {
|
func (bc *Blockchain) verifyTx(t *transaction.Transaction, block *block.Block) error {
|
||||||
height := bc.BlockHeight()
|
height := bc.BlockHeight()
|
||||||
if t.ValidUntilBlock <= height || t.ValidUntilBlock > height+transaction.MaxValidUntilBlockIncrement {
|
if t.ValidUntilBlock <= height || t.ValidUntilBlock > height+transaction.MaxValidUntilBlockIncrement {
|
||||||
return errors.Errorf("transaction has expired. ValidUntilBlock = %d, current height = %d", t.ValidUntilBlock, height)
|
return fmt.Errorf("transaction has expired. ValidUntilBlock = %d, current height = %d", t.ValidUntilBlock, height)
|
||||||
}
|
}
|
||||||
hashes, err := bc.GetScriptHashesForVerifying(t)
|
// Policying.
|
||||||
if err != nil {
|
if err := bc.contracts.Policy.CheckPolicy(bc.dao, t); err != nil {
|
||||||
return err
|
// Only one %w can be used.
|
||||||
}
|
return fmt.Errorf("%w: %v", ErrPolicy, err)
|
||||||
blockedAccounts, err := bc.contracts.Policy.GetBlockedAccountsInternal(bc.dao)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, h := range hashes {
|
|
||||||
i := sort.Search(len(blockedAccounts), func(i int) bool {
|
|
||||||
return !blockedAccounts[i].Less(h)
|
|
||||||
})
|
|
||||||
if i != len(blockedAccounts) && blockedAccounts[i].Equals(h) {
|
|
||||||
return errors.Errorf("policy check failed: account %s is blocked", h.StringLE())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
maxBlockSystemFee := bc.contracts.Policy.GetMaxBlockSystemFeeInternal(bc.dao)
|
|
||||||
if maxBlockSystemFee < t.SystemFee {
|
|
||||||
return errors.Errorf("policy check failed: transaction's fee shouldn't exceed maximum block system fee %d", maxBlockSystemFee)
|
|
||||||
}
|
}
|
||||||
balance := bc.GetUtilityTokenBalance(t.Sender())
|
balance := bc.GetUtilityTokenBalance(t.Sender())
|
||||||
need := t.SystemFee + t.NetworkFee
|
need := t.SystemFee + t.NetworkFee
|
||||||
if balance.Cmp(big.NewInt(need)) < 0 {
|
if balance.Cmp(big.NewInt(need)) < 0 {
|
||||||
return errors.Errorf("insufficient funds: balance is %v, need: %v", balance, need)
|
return fmt.Errorf("insufficient funds: balance is %v, need: %v", balance, need)
|
||||||
}
|
}
|
||||||
size := io.GetVarSize(t)
|
size := io.GetVarSize(t)
|
||||||
if size > transaction.MaxTransactionSize {
|
if size > transaction.MaxTransactionSize {
|
||||||
return errors.Errorf("invalid transaction size = %d. It shoud be less then MaxTransactionSize = %d", io.GetVarSize(t), transaction.MaxTransactionSize)
|
return fmt.Errorf("too big transaction (%d > MaxTransactionSize %d)", size, transaction.MaxTransactionSize)
|
||||||
}
|
}
|
||||||
needNetworkFee := int64(size) * bc.FeePerByte()
|
needNetworkFee := int64(size) * bc.FeePerByte()
|
||||||
netFee := t.NetworkFee - needNetworkFee
|
netFee := t.NetworkFee - needNetworkFee
|
||||||
if netFee < 0 {
|
if netFee < 0 {
|
||||||
return errors.Errorf("insufficient funds: net fee is %v, need %v", t.NetworkFee, needNetworkFee)
|
return fmt.Errorf("insufficient funds: net fee is %v, need %v", t.NetworkFee, needNetworkFee)
|
||||||
}
|
}
|
||||||
if block == nil {
|
if block == nil {
|
||||||
if ok := bc.memPool.Verify(t, bc); !ok {
|
if ok := bc.memPool.Verify(t, bc); !ok {
|
||||||
|
@ -1286,7 +1270,7 @@ func (bc *Blockchain) AddStateRoot(r *state.MPTRoot) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := bc.verifyStateRoot(r); err != nil {
|
if err := bc.verifyStateRoot(r); err != nil {
|
||||||
return errors.WithMessage(err, "invalid state root")
|
return fmt.Errorf("invalid state root: %w", err)
|
||||||
}
|
}
|
||||||
if r.Index > bc.BlockHeight() { // just put it into the store for future checks
|
if r.Index > bc.BlockHeight() { // just put it into the store for future checks
|
||||||
return bc.dao.PutStateRoot(&state.MPTRootState{
|
return bc.dao.PutStateRoot(&state.MPTRootState{
|
||||||
|
@ -1298,7 +1282,7 @@ func (bc *Blockchain) AddStateRoot(r *state.MPTRoot) error {
|
||||||
flag := state.Unverified
|
flag := state.Unverified
|
||||||
if r.Witness != nil {
|
if r.Witness != nil {
|
||||||
if err := bc.verifyStateRootWitness(r); err != nil {
|
if err := bc.verifyStateRootWitness(r); err != nil {
|
||||||
return errors.WithMessage(err, "can't verify signature")
|
return fmt.Errorf("can't verify signature: %w", err)
|
||||||
}
|
}
|
||||||
flag = state.Verified
|
flag = state.Verified
|
||||||
}
|
}
|
||||||
|
@ -1315,7 +1299,7 @@ func (bc *Blockchain) AddStateRoot(r *state.MPTRoot) error {
|
||||||
func (bc *Blockchain) updateStateHeight(newHeight uint32) error {
|
func (bc *Blockchain) updateStateHeight(newHeight uint32) error {
|
||||||
h, err := bc.dao.GetCurrentStateRootHeight()
|
h, err := bc.dao.GetCurrentStateRootHeight()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.WithMessage(err, "can't get current state root height")
|
return fmt.Errorf("can't get current state root height: %w", err)
|
||||||
} else if newHeight == h+1 {
|
} else if newHeight == h+1 {
|
||||||
updateStateHeightMetric(newHeight)
|
updateStateHeightMetric(newHeight)
|
||||||
return bc.dao.PutCurrentStateRootHeight(h + 1)
|
return bc.dao.PutCurrentStateRootHeight(h + 1)
|
||||||
|
@ -1367,23 +1351,17 @@ func (bc *Blockchain) PoolTx(t *transaction.Transaction) error {
|
||||||
defer bc.lock.RUnlock()
|
defer bc.lock.RUnlock()
|
||||||
|
|
||||||
if bc.HasTransaction(t.Hash()) {
|
if bc.HasTransaction(t.Hash()) {
|
||||||
return ErrAlreadyExists
|
return fmt.Errorf("blockchain: %w", ErrAlreadyExists)
|
||||||
}
|
}
|
||||||
if err := bc.verifyTx(t, nil); err != nil {
|
if err := bc.verifyTx(t, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Policying.
|
|
||||||
if ok, err := bc.contracts.Policy.CheckPolicy(bc.newInteropContext(trigger.Application, bc.dao, nil, t), t); err != nil {
|
|
||||||
return err
|
|
||||||
} else if !ok {
|
|
||||||
return ErrPolicy
|
|
||||||
}
|
|
||||||
if err := bc.memPool.Add(t, bc); err != nil {
|
if err := bc.memPool.Add(t, bc); err != nil {
|
||||||
switch err {
|
switch {
|
||||||
case mempool.ErrOOM:
|
case errors.Is(err, mempool.ErrOOM):
|
||||||
return ErrOOM
|
return ErrOOM
|
||||||
case mempool.ErrConflict:
|
case errors.Is(err, mempool.ErrDup):
|
||||||
return ErrAlreadyExists
|
return fmt.Errorf("mempool: %w", ErrAlreadyExists)
|
||||||
default:
|
default:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1416,19 +1394,6 @@ func (bc *Blockchain) GetEnrollments() ([]state.Validator, error) {
|
||||||
return bc.contracts.NEO.GetCandidates(bc.dao)
|
return bc.contracts.NEO.GetCandidates(bc.dao)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScriptHashesForVerifying returns all the ScriptHashes of a transaction which will be use
|
|
||||||
// to verify whether the transaction is bonafide or not.
|
|
||||||
// Golang implementation of GetScriptHashesForVerifying method in C# (https://github.com/neo-project/neo/blob/master/neo/Network/P2P/Payloads/Transaction.cs#L190)
|
|
||||||
func (bc *Blockchain) GetScriptHashesForVerifying(t *transaction.Transaction) ([]util.Uint160, error) {
|
|
||||||
hashesResult := make([]util.Uint160, len(t.Signers))
|
|
||||||
for i, s := range t.Signers {
|
|
||||||
hashesResult[i] = s.Account
|
|
||||||
}
|
|
||||||
|
|
||||||
return hashesResult, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTestVM returns a VM and a Store setup for a test run of some sort of code.
|
// GetTestVM returns a VM and a Store setup for a test run of some sort of code.
|
||||||
func (bc *Blockchain) GetTestVM(tx *transaction.Transaction) *vm.VM {
|
func (bc *Blockchain) GetTestVM(tx *transaction.Transaction) *vm.VM {
|
||||||
systemInterop := bc.newInteropContext(trigger.Application, bc.dao, nil, tx)
|
systemInterop := bc.newInteropContext(trigger.Application, bc.dao, nil, tx)
|
||||||
|
@ -1479,12 +1444,12 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
|
||||||
}
|
}
|
||||||
err = vm.Run()
|
err = vm.Run()
|
||||||
if vm.HasFailed() {
|
if vm.HasFailed() {
|
||||||
return errors.Errorf("vm failed to execute the script with error: %s", err)
|
return fmt.Errorf("vm execution has failed: %w", err)
|
||||||
}
|
}
|
||||||
resEl := vm.Estack().Pop()
|
resEl := vm.Estack().Pop()
|
||||||
if resEl != nil {
|
if resEl != nil {
|
||||||
if !resEl.Bool() {
|
if !resEl.Bool() {
|
||||||
return errors.Errorf("signature check failed")
|
return fmt.Errorf("signature check failed")
|
||||||
}
|
}
|
||||||
if useKeys {
|
if useKeys {
|
||||||
bc.keyCacheLock.RLock()
|
bc.keyCacheLock.RLock()
|
||||||
|
@ -1497,7 +1462,7 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return errors.Errorf("no result returned from the script")
|
return fmt.Errorf("no result returned from the script")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1509,23 +1474,14 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
|
||||||
// not yet added into any block.
|
// not yet added into any block.
|
||||||
// Golang implementation of VerifyWitnesses method in C# (https://github.com/neo-project/neo/blob/master/neo/SmartContract/Helper.cs#L87).
|
// Golang implementation of VerifyWitnesses method in C# (https://github.com/neo-project/neo/blob/master/neo/SmartContract/Helper.cs#L87).
|
||||||
func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *block.Block) error {
|
func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *block.Block) error {
|
||||||
hashes, err := bc.GetScriptHashesForVerifying(t)
|
if len(t.Signers) != len(t.Scripts) {
|
||||||
if err != nil {
|
return fmt.Errorf("number of signers doesn't match witnesses (%d vs %d)", len(t.Signers), len(t.Scripts))
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
witnesses := t.Scripts
|
|
||||||
if len(hashes) != len(witnesses) {
|
|
||||||
return errors.Errorf("expected len(hashes) == len(witnesses). got: %d != %d", len(hashes), len(witnesses))
|
|
||||||
}
|
|
||||||
sort.Slice(hashes, func(i, j int) bool { return hashes[i].Less(hashes[j]) })
|
|
||||||
sort.Slice(witnesses, func(i, j int) bool { return witnesses[i].ScriptHash().Less(witnesses[j].ScriptHash()) })
|
|
||||||
interopCtx := bc.newInteropContext(trigger.Verification, bc.dao, block, t)
|
interopCtx := bc.newInteropContext(trigger.Verification, bc.dao, block, t)
|
||||||
for i := 0; i < len(hashes); i++ {
|
for i := range t.Signers {
|
||||||
err := bc.verifyHashAgainstScript(hashes[i], &witnesses[i], interopCtx, false, t.NetworkFee)
|
err := bc.verifyHashAgainstScript(t.Signers[i].Account, &t.Scripts[i], interopCtx, false, t.NetworkFee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
numStr := fmt.Sprintf("witness #%d", i)
|
return fmt.Errorf("witness #%d: %w", i, err)
|
||||||
return errors.Wrap(err, numStr)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ type Blockchainer interface {
|
||||||
GetValidators() ([]*keys.PublicKey, error)
|
GetValidators() ([]*keys.PublicKey, error)
|
||||||
GetStandByCommittee() keys.PublicKeys
|
GetStandByCommittee() keys.PublicKeys
|
||||||
GetStandByValidators() keys.PublicKeys
|
GetStandByValidators() keys.PublicKeys
|
||||||
GetScriptHashesForVerifying(*transaction.Transaction) ([]util.Uint160, error)
|
|
||||||
GetStateRoot(height uint32) (*state.MPTRootState, error)
|
GetStateRoot(height uint32) (*state.MPTRootState, error)
|
||||||
GetStorageItem(id int32, key []byte) *state.StorageItem
|
GetStorageItem(id int32, key []byte) *state.StorageItem
|
||||||
GetStorageItems(id int32) (map[string]*state.StorageItem, error)
|
GetStorageItems(id int32) (map[string]*state.StorageItem, error)
|
||||||
|
|
|
@ -26,7 +26,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"go.uber.org/zap/zaptest"
|
"go.uber.org/zap/zaptest"
|
||||||
)
|
)
|
||||||
|
@ -396,7 +395,7 @@ func signTx(bc *Blockchain, txs ...*transaction.Transaction) error {
|
||||||
validators := bc.GetStandByValidators()
|
validators := bc.GetStandByValidators()
|
||||||
rawScript, err := smartcontract.CreateMultiSigRedeemScript(bc.config.ValidatorsCount/2+1, validators)
|
rawScript, err := smartcontract.CreateMultiSigRedeemScript(bc.config.ValidatorsCount/2+1, validators)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "fail to sign tx")
|
return fmt.Errorf("failed to sign tx: %w", err)
|
||||||
}
|
}
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
size := io.GetVarSize(tx)
|
size := io.GetVarSize(tx)
|
||||||
|
|
|
@ -62,14 +62,14 @@ func ecdsaCheckMultisig(ic *interop.Context, v *vm.VM, curve elliptic.Curve) err
|
||||||
hashToCheck := hash.Sha256(msg).BytesBE()
|
hashToCheck := hash.Sha256(msg).BytesBE()
|
||||||
pkeys, err := v.Estack().PopSigElements()
|
pkeys, err := v.Estack().PopSigElements()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("wrong parameters: %s", err.Error())
|
return fmt.Errorf("wrong parameters: %w", err)
|
||||||
}
|
}
|
||||||
if !v.AddGas(ECDSAVerifyPrice * int64(len(pkeys))) {
|
if !v.AddGas(ECDSAVerifyPrice * int64(len(pkeys))) {
|
||||||
return errors.New("gas limit exceeded")
|
return errors.New("gas limit exceeded")
|
||||||
}
|
}
|
||||||
sigs, err := v.Estack().PopSigElements()
|
sigs, err := v.Estack().PopSigElements()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("wrong parameters: %s", err.Error())
|
return fmt.Errorf("wrong parameters: %w", err)
|
||||||
}
|
}
|
||||||
// It's ok to have more keys than there are signatures (it would
|
// It's ok to have more keys than there are signatures (it would
|
||||||
// just mean that some keys didn't sign), but not the other way around.
|
// just mean that some keys didn't sign), but not the other way around.
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"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/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GasLeft returns remaining amount of GAS.
|
// GasLeft returns remaining amount of GAS.
|
||||||
|
|
|
@ -2,6 +2,8 @@ package runtime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"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"
|
||||||
|
@ -9,7 +11,6 @@ import (
|
||||||
"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/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckHashedWitness checks given hash against current list of script hashes
|
// CheckHashedWitness checks given hash against current list of script hashes
|
||||||
|
@ -91,7 +92,7 @@ func CheckWitness(ic *interop.Context, v *vm.VM) error {
|
||||||
res, err = CheckHashedWitness(ic, hash)
|
res, err = CheckHashedWitness(ic, hash)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to check")
|
return fmt.Errorf("failed to check witness: %w", err)
|
||||||
}
|
}
|
||||||
v.Estack().PushVal(res)
|
v.Estack().PushVal(res)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -74,7 +74,7 @@ func createContractStateFromVM(ic *interop.Context, v *vm.VM) (*state.Contract,
|
||||||
var m manifest.Manifest
|
var m manifest.Manifest
|
||||||
err := m.UnmarshalJSON(manifestBytes)
|
err := m.UnmarshalJSON(manifestBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to retrieve manifest from stack: %v", err)
|
return nil, fmt.Errorf("unable to retrieve manifest from stack: %w", err)
|
||||||
}
|
}
|
||||||
return &state.Contract{
|
return &state.Contract{
|
||||||
Script: script,
|
Script: script,
|
||||||
|
@ -105,7 +105,7 @@ func contractCreate(ic *interop.Context, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
cs, err := contractToStackItem(newcontract)
|
cs, err := contractToStackItem(newcontract)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot convert contract to stack item: %v", err)
|
return fmt.Errorf("cannot convert contract to stack item: %w", err)
|
||||||
}
|
}
|
||||||
v.Estack().PushVal(cs)
|
v.Estack().PushVal(cs)
|
||||||
return nil
|
return nil
|
||||||
|
@ -149,10 +149,10 @@ func contractUpdate(ic *interop.Context, v *vm.VM) error {
|
||||||
}
|
}
|
||||||
contract.Manifest.ABI.Hash = newHash
|
contract.Manifest.ABI.Hash = newHash
|
||||||
if err := ic.DAO.PutContractState(contract); err != nil {
|
if err := ic.DAO.PutContractState(contract); err != nil {
|
||||||
return fmt.Errorf("failed to update script: %v", err)
|
return fmt.Errorf("failed to update script: %w", err)
|
||||||
}
|
}
|
||||||
if err := ic.DAO.DeleteContractState(oldHash); err != nil {
|
if err := ic.DAO.DeleteContractState(oldHash); err != nil {
|
||||||
return fmt.Errorf("failed to update script: %v", err)
|
return fmt.Errorf("failed to update script: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if manifest was provided, update the old contract manifest and check associated
|
// if manifest was provided, update the old contract manifest and check associated
|
||||||
|
@ -161,7 +161,7 @@ func contractUpdate(ic *interop.Context, v *vm.VM) error {
|
||||||
var newManifest manifest.Manifest
|
var newManifest manifest.Manifest
|
||||||
err := newManifest.UnmarshalJSON(manifestBytes)
|
err := newManifest.UnmarshalJSON(manifestBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve manifest from stack: %v", err)
|
return fmt.Errorf("unable to retrieve manifest from stack: %w", err)
|
||||||
}
|
}
|
||||||
// we don't have to perform `GetContractState` one more time as it's already up-to-date
|
// we don't have to perform `GetContractState` one more time as it's already up-to-date
|
||||||
contract.Manifest = newManifest
|
contract.Manifest = newManifest
|
||||||
|
@ -171,14 +171,14 @@ func contractUpdate(ic *interop.Context, v *vm.VM) error {
|
||||||
if !contract.HasStorage() {
|
if !contract.HasStorage() {
|
||||||
siMap, err := ic.DAO.GetStorageItems(contract.ID)
|
siMap, err := ic.DAO.GetStorageItems(contract.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to update manifest: %v", err)
|
return fmt.Errorf("failed to update manifest: %w", err)
|
||||||
}
|
}
|
||||||
if len(siMap) != 0 {
|
if len(siMap) != 0 {
|
||||||
return errors.New("old contract shouldn't have storage")
|
return errors.New("old contract shouldn't have storage")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := ic.DAO.PutContractState(contract); err != nil {
|
if err := ic.DAO.PutContractState(contract); err != nil {
|
||||||
return fmt.Errorf("failed to update manifest: %v", err)
|
return fmt.Errorf("failed to update manifest: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ func Deploy(ic *interop.Context, _ *vm.VM) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := native.Initialize(ic); err != nil {
|
if err := native.Initialize(ic); err != nil {
|
||||||
return fmt.Errorf("initializing %s native contract: %v", md.Name, err)
|
return fmt.Errorf("initializing %s native contract: %w", md.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -92,7 +92,7 @@ func (g *GAS) OnPersist(ic *interop.Context) error {
|
||||||
}
|
}
|
||||||
validators, err := g.NEO.getNextBlockValidatorsInternal(ic.Chain, ic.DAO)
|
validators, err := g.NEO.getNextBlockValidatorsInternal(ic.Chain, ic.DAO)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot get block validators: %v", err)
|
return fmt.Errorf("can't get block validators: %w", err)
|
||||||
}
|
}
|
||||||
primary := validators[ic.Block.ConsensusData.PrimaryIndex].GetScriptHash()
|
primary := validators[ic.Block.ConsensusData.PrimaryIndex].GetScriptHash()
|
||||||
var netFee int64
|
var netFee int64
|
||||||
|
|
|
@ -2,6 +2,7 @@ package native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -18,7 +19,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NEO represents NEO native contract.
|
// NEO represents NEO native contract.
|
||||||
|
|
|
@ -2,6 +2,8 @@ package native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -15,7 +17,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -508,23 +509,27 @@ func (p *Policy) checkValidators(ic *interop.Context) (bool, error) {
|
||||||
return runtime.CheckHashedWitness(ic, prevBlock.NextConsensus)
|
return runtime.CheckHashedWitness(ic, prevBlock.NextConsensus)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckPolicy checks whether transaction's script hashes for verifying are
|
// CheckPolicy checks whether transaction conforms to current policy restrictions
|
||||||
// included into blocked accounts list.
|
// like not being signed by blocked account or not exceeding block-level system
|
||||||
func (p *Policy) CheckPolicy(ic *interop.Context, tx *transaction.Transaction) (bool, error) {
|
// fee limit.
|
||||||
ba, err := p.GetBlockedAccountsInternal(ic.DAO)
|
func (p *Policy) CheckPolicy(d dao.DAO, tx *transaction.Transaction) error {
|
||||||
|
ba, err := p.GetBlockedAccountsInternal(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return fmt.Errorf("unable to get blocked accounts list: %w", err)
|
||||||
}
|
}
|
||||||
scriptHashes, err := ic.Chain.GetScriptHashesForVerifying(tx)
|
if len(ba) > 0 {
|
||||||
if err != nil {
|
for _, signer := range tx.Signers {
|
||||||
return false, err
|
i := sort.Search(len(ba), func(i int) bool {
|
||||||
}
|
return !ba[i].Less(signer.Account)
|
||||||
for _, acc := range ba {
|
})
|
||||||
for _, hash := range scriptHashes {
|
if i != len(ba) && ba[i].Equals(signer.Account) {
|
||||||
if acc.Equals(hash) {
|
return fmt.Errorf("account %s is blocked", signer.Account.StringLE())
|
||||||
return false, nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true, nil
|
maxBlockSystemFee := p.GetMaxBlockSystemFeeInternal(d)
|
||||||
|
if maxBlockSystemFee < tx.SystemFee {
|
||||||
|
return fmt.Errorf("transaction's fee can't exceed maximum block system fee %d", maxBlockSystemFee)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ func NewBoltDBStore(cfg BoltDBOptions) (*BoltDBStore, error) {
|
||||||
err = db.Update(func(tx *bbolt.Tx) error {
|
err = db.Update(func(tx *bbolt.Tx) error {
|
||||||
_, err = tx.CreateBucketIfNotExists(Bucket)
|
_, err = tx.CreateBucketIfNotExists(Bucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not create root bucket: %v", err)
|
return fmt.Errorf("could not create root bucket: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
@ -16,7 +17,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// coordLen is the number of bytes in serialized X or Y coordinate.
|
// coordLen is the number of bytes in serialized X or Y coordinate.
|
||||||
|
@ -267,7 +267,7 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
r.Err = errors.Errorf("invalid prefix %d", prefix)
|
r.Err = fmt.Errorf("invalid prefix %d", prefix)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if x.Cmp(curveParams.P) >= 0 || y.Cmp(curveParams.P) >= 0 {
|
if x.Cmp(curveParams.P) >= 0 || y.Cmp(curveParams.P) >= 0 {
|
||||||
|
|
|
@ -2,10 +2,10 @@ package base58
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/mr-tron/base58"
|
"github.com/mr-tron/base58"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckDecode implements a base58-encoded string decoding with hash-based
|
// CheckDecode implements a base58-encoded string decoding with hash-based
|
||||||
|
|
|
@ -12,7 +12,7 @@ func MakeDirForFile(filePath string, creator string) error {
|
||||||
dir := path.Dir(fileName)
|
dir := path.Dir(fileName)
|
||||||
err := os.MkdirAll(dir, os.ModePerm)
|
err := os.MkdirAll(dir, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not create dir for %s: %v", creator, err)
|
return fmt.Errorf("could not create dir for %s: %w", creator, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,9 +112,6 @@ func (chain testChain) GetStandByValidators() keys.PublicKeys {
|
||||||
func (chain testChain) GetEnrollments() ([]state.Validator, error) {
|
func (chain testChain) GetEnrollments() ([]state.Validator, error) {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
func (chain testChain) GetScriptHashesForVerifying(*transaction.Transaction) ([]util.Uint160, error) {
|
|
||||||
panic("TODO")
|
|
||||||
}
|
|
||||||
func (chain testChain) GetStateRoot(height uint32) (*state.MPTRootState, error) {
|
func (chain testChain) GetStateRoot(height uint32) (*state.MPTRootState, error) {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package payload
|
package payload
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"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/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Headers payload.
|
// Headers payload.
|
||||||
|
@ -19,7 +20,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrTooManyHeaders is an error returned when too many headers were received.
|
// ErrTooManyHeaders is an error returned when too many headers were received.
|
||||||
var ErrTooManyHeaders = errors.Errorf("too many headers were received (max: %d)", MaxHeadersAllowed)
|
var ErrTooManyHeaders = fmt.Errorf("too many headers were received (max: %d)", MaxHeadersAllowed)
|
||||||
|
|
||||||
// DecodeBinary implements Serializable interface.
|
// DecodeBinary implements Serializable interface.
|
||||||
func (p *Headers) DecodeBinary(br *io.BinReader) {
|
func (p *Headers) DecodeBinary(br *io.BinReader) {
|
||||||
|
|
|
@ -843,12 +843,12 @@ func (s *Server) relayBlocksLoop() {
|
||||||
// verifyAndPoolTX verifies the TX and adds it to the local mempool.
|
// verifyAndPoolTX verifies the TX and adds it to the local mempool.
|
||||||
func (s *Server) verifyAndPoolTX(t *transaction.Transaction) RelayReason {
|
func (s *Server) verifyAndPoolTX(t *transaction.Transaction) RelayReason {
|
||||||
if err := s.chain.PoolTx(t); err != nil {
|
if err := s.chain.PoolTx(t); err != nil {
|
||||||
switch err {
|
switch {
|
||||||
case core.ErrAlreadyExists:
|
case errors.Is(err, core.ErrAlreadyExists):
|
||||||
return RelayAlreadyExists
|
return RelayAlreadyExists
|
||||||
case core.ErrOOM:
|
case errors.Is(err, core.ErrOOM):
|
||||||
return RelayOutOfMemory
|
return RelayOutOfMemory
|
||||||
case core.ErrPolicy:
|
case errors.Is(err, core.ErrPolicy):
|
||||||
return RelayPolicyFail
|
return RelayPolicyFail
|
||||||
default:
|
default:
|
||||||
return RelayInvalid
|
return RelayInvalid
|
||||||
|
|
|
@ -161,7 +161,7 @@ func (p *TCPPeer) handleConn() {
|
||||||
}
|
}
|
||||||
if err = p.server.handleMessage(p, msg); err != nil {
|
if err = p.server.handleMessage(p, msg); err != nil {
|
||||||
if p.Handshaked() {
|
if p.Handshaked() {
|
||||||
err = fmt.Errorf("handling %s message: %v", msg.Command.String(), err)
|
err = fmt.Errorf("handling %s message: %w", msg.Command.String(), err)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -15,7 +16,6 @@ import (
|
||||||
"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/rpc/request"
|
"github.com/nspcc-dev/neo-go/pkg/rpc/request"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response"
|
"github.com/nspcc-dev/neo-go/pkg/rpc/response"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -123,7 +123,7 @@ func (c *Client) SetWIF(wif string) error {
|
||||||
defer c.wifMu.Unlock()
|
defer c.wifMu.Unlock()
|
||||||
decodedWif, err := keys.WIFDecode(wif, 0x00)
|
decodedWif, err := keys.WIFDecode(wif, 0x00)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Failed to decode WIF; failed to add WIF to client ")
|
return fmt.Errorf("failed to decode WIF: %w", err)
|
||||||
}
|
}
|
||||||
c.wif = decodedWif
|
c.wif = decodedWif
|
||||||
return nil
|
return nil
|
||||||
|
@ -176,7 +176,7 @@ func (c *Client) makeHTTPRequest(r *request.Raw) (*response.Raw, error) {
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
err = fmt.Errorf("HTTP %d/%s", resp.StatusCode, http.StatusText(resp.StatusCode))
|
err = fmt.Errorf("HTTP %d/%s", resp.StatusCode, http.StatusText(resp.StatusCode))
|
||||||
} else {
|
} else {
|
||||||
err = errors.Wrap(err, "JSON decoding")
|
err = fmt.Errorf("JSON decoding: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -123,7 +123,7 @@ func (c *Client) CreateNEP5TransferTx(acc *wallet.Account, to util.Uint160, toke
|
||||||
func (c *Client) CreateNEP5MultiTransferTx(acc *wallet.Account, gas int64, recepients ...TransferTarget) (*transaction.Transaction, error) {
|
func (c *Client) CreateNEP5MultiTransferTx(acc *wallet.Account, gas int64, recepients ...TransferTarget) (*transaction.Transaction, error) {
|
||||||
from, err := address.StringToUint160(acc.Address)
|
from, err := address.StringToUint160(acc.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("bad account address: %v", err)
|
return nil, fmt.Errorf("bad account address: %w", err)
|
||||||
}
|
}
|
||||||
w := io.NewBufBinWriter()
|
w := io.NewBufBinWriter()
|
||||||
for i := range recepients {
|
for i := range recepients {
|
||||||
|
@ -147,7 +147,7 @@ func (c *Client) CreateTxFromScript(script []byte, acc *wallet.Account, gas int6
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't add system fee to transaction: %v", err)
|
return nil, fmt.Errorf("can't add system fee to transaction: %w", err)
|
||||||
}
|
}
|
||||||
tx := transaction.New(c.opts.Network, script, result.GasConsumed)
|
tx := transaction.New(c.opts.Network, script, result.GasConsumed)
|
||||||
tx.Signers = []transaction.Signer{
|
tx.Signers = []transaction.Signer{
|
||||||
|
@ -158,12 +158,12 @@ func (c *Client) CreateTxFromScript(script []byte, acc *wallet.Account, gas int6
|
||||||
}
|
}
|
||||||
tx.ValidUntilBlock, err = c.CalculateValidUntilBlock()
|
tx.ValidUntilBlock, err = c.CalculateValidUntilBlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't calculate validUntilBlock: %v", err)
|
return nil, fmt.Errorf("can't calculate validUntilBlock: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.AddNetworkFee(tx, gas, acc)
|
err = c.AddNetworkFee(tx, gas, acc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't add network fee to transaction: %v", err)
|
return nil, fmt.Errorf("can't add network fee to transaction: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return tx, nil
|
return tx, nil
|
||||||
|
@ -180,7 +180,7 @@ func (c *Client) TransferNEP5(acc *wallet.Account, to util.Uint160, token util.U
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := acc.SignTx(tx); err != nil {
|
if err := acc.SignTx(tx); err != nil {
|
||||||
return util.Uint256{}, fmt.Errorf("can't sign tx: %v", err)
|
return util.Uint256{}, fmt.Errorf("can't sign tx: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.SendRawTransaction(tx)
|
return c.SendRawTransaction(tx)
|
||||||
|
@ -194,7 +194,7 @@ func (c *Client) MultiTransferNEP5(acc *wallet.Account, gas int64, recepients ..
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := acc.SignTx(tx); err != nil {
|
if err := acc.SignTx(tx); err != nil {
|
||||||
return util.Uint256{}, fmt.Errorf("can't sign tx: %v", err)
|
return util.Uint256{}, fmt.Errorf("can't sign tx: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.SendRawTransaction(tx)
|
return c.SendRawTransaction(tx)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native"
|
"github.com/nspcc-dev/neo-go/pkg/core/native"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PolicyContractHash represents a hash of native Policy contract.
|
// PolicyContractHash represents a hash of native Policy contract.
|
||||||
|
|
|
@ -2,6 +2,7 @@ package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||||
|
@ -16,7 +17,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetApplicationLog returns the contract log based on the specified txid.
|
// GetApplicationLog returns the contract log based on the specified txid.
|
||||||
|
@ -428,28 +428,28 @@ func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sys
|
||||||
|
|
||||||
addr, err := address.StringToUint160(acc.Address)
|
addr, err := address.StringToUint160(acc.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return txHash, errors.Wrap(err, "failed to get address")
|
return txHash, fmt.Errorf("failed to get address: %w", err)
|
||||||
}
|
}
|
||||||
tx.Signers = getSigners(addr, cosigners)
|
tx.Signers = getSigners(addr, cosigners)
|
||||||
|
|
||||||
validUntilBlock, err := c.CalculateValidUntilBlock()
|
validUntilBlock, err := c.CalculateValidUntilBlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return txHash, errors.Wrap(err, "failed to add validUntilBlock to transaction")
|
return txHash, fmt.Errorf("failed to add validUntilBlock to transaction: %w", err)
|
||||||
}
|
}
|
||||||
tx.ValidUntilBlock = validUntilBlock
|
tx.ValidUntilBlock = validUntilBlock
|
||||||
|
|
||||||
err = c.AddNetworkFee(tx, int64(netfee), acc)
|
err = c.AddNetworkFee(tx, int64(netfee), acc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return txHash, errors.Wrapf(err, "failed to add network fee")
|
return txHash, fmt.Errorf("failed to add network fee: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = acc.SignTx(tx); err != nil {
|
if err = acc.SignTx(tx); err != nil {
|
||||||
return txHash, errors.Wrap(err, "failed to sign tx")
|
return txHash, fmt.Errorf("failed to sign tx: %w", err)
|
||||||
}
|
}
|
||||||
txHash = tx.Hash()
|
txHash = tx.Hash()
|
||||||
actualHash, err := c.SendRawTransaction(tx)
|
actualHash, err := c.SendRawTransaction(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return txHash, errors.Wrap(err, "failed sendning tx")
|
return txHash, fmt.Errorf("failed to send tx: %w", err)
|
||||||
}
|
}
|
||||||
if !actualHash.Equals(txHash) {
|
if !actualHash.Equals(txHash) {
|
||||||
return actualHash, fmt.Errorf("sent and actual tx hashes mismatch:\n\tsent: %v\n\tactual: %v", txHash.StringLE(), actualHash.StringLE())
|
return actualHash, fmt.Errorf("sent and actual tx hashes mismatch:\n\tsent: %v\n\tactual: %v", txHash.StringLE(), actualHash.StringLE())
|
||||||
|
@ -505,7 +505,7 @@ func (c *Client) CalculateValidUntilBlock() (uint32, error) {
|
||||||
)
|
)
|
||||||
blockCount, err := c.GetBlockCount()
|
blockCount, err := c.GetBlockCount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, errors.Wrapf(err, "cannot get block count")
|
return result, fmt.Errorf("can't get block count: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.cache.calculateValidUntilBlock.expiresAt > blockCount {
|
if c.cache.calculateValidUntilBlock.expiresAt > blockCount {
|
||||||
|
@ -513,7 +513,7 @@ func (c *Client) CalculateValidUntilBlock() (uint32, error) {
|
||||||
} else {
|
} else {
|
||||||
validators, err := c.GetValidators()
|
validators, err := c.GetValidators()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, errors.Wrapf(err, "cannot get validators")
|
return result, fmt.Errorf("can't get validators: %w", err)
|
||||||
}
|
}
|
||||||
validatorsCount = uint32(len(validators))
|
validatorsCount = uint32(len(validators))
|
||||||
c.cache.calculateValidUntilBlock = calculateValidUntilBlockCache{
|
c.cache.calculateValidUntilBlock = calculateValidUntilBlockCache{
|
||||||
|
|
|
@ -28,7 +28,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -577,7 +576,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
||||||
result: func(c *Client) interface{} {
|
result: func(c *Client) interface{} {
|
||||||
addr, err := address.StringToUint160("NMipL5VsNoLUBUJKPKLhxaEbPQVCZnyJyB")
|
addr, err := address.StringToUint160("NMipL5VsNoLUBUJKPKLhxaEbPQVCZnyJyB")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(errors.Wrap(err, "failed to parse UnclaimedGas address"))
|
panic(fmt.Errorf("failed to parse UnclaimedGas address: %w", err))
|
||||||
}
|
}
|
||||||
return result.UnclaimedGas{
|
return result.UnclaimedGas{
|
||||||
Address: addr,
|
Address: addr,
|
||||||
|
@ -691,7 +690,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
||||||
result: func(c *Client) interface{} {
|
result: func(c *Client) interface{} {
|
||||||
h, err := util.Uint256DecodeStringLE("72159b0cf1221110daad6e1df6ef4ff03012173b63c86910bd7134deb659c875")
|
h, err := util.Uint256DecodeStringLE("72159b0cf1221110daad6e1df6ef4ff03012173b63c86910bd7134deb659c875")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("can't decode `sendrawtransaction` result hash: %v", err))
|
panic(fmt.Errorf("can't decode `sendrawtransaction` result hash: %w", err))
|
||||||
}
|
}
|
||||||
return h
|
return h
|
||||||
},
|
},
|
||||||
|
@ -711,7 +710,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
||||||
result: func(c *Client) interface{} {
|
result: func(c *Client) interface{} {
|
||||||
h, err := util.Uint256DecodeStringLE("1bdea8f80eb5bd97fade38d5e7fb93b02c9d3e01394e9f4324218132293f7ea6")
|
h, err := util.Uint256DecodeStringLE("1bdea8f80eb5bd97fade38d5e7fb93b02c9d3e01394e9f4324218132293f7ea6")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("can't decode `submitblock` result hash: %v", err))
|
panic(fmt.Errorf("can't decode `submitblock` result hash: %w", err))
|
||||||
}
|
}
|
||||||
return h
|
return h
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
@ -12,7 +13,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
|
|
@ -2,9 +2,8 @@ package request
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -60,11 +59,11 @@ func (r *In) DecodeData(data io.ReadCloser) error {
|
||||||
|
|
||||||
err := json.NewDecoder(data).Decode(r)
|
err := json.NewDecoder(data).Decode(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("error parsing JSON payload: %s", err)
|
return fmt.Errorf("error parsing JSON payload: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.JSONRPC != JSONRPCVersion {
|
if r.JSONRPC != JSONRPCVersion {
|
||||||
return errors.Errorf("invalid version, expected 2.0 got: '%s'", r.JSONRPC)
|
return fmt.Errorf("invalid version, expected 2.0 got: '%s'", r.JSONRPC)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -77,7 +76,7 @@ func (r *In) Params() (*Params, error) {
|
||||||
|
|
||||||
err := json.Unmarshal(r.RawParams, ¶ms)
|
err := json.Unmarshal(r.RawParams, ¶ms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("error parsing params field in payload: %s", err)
|
return nil, fmt.Errorf("error parsing params: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ¶ms, nil
|
return ¶ms, nil
|
||||||
|
|
|
@ -2,8 +2,7 @@ package response
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
@ -30,7 +31,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -614,7 +614,7 @@ func (s *Server) getDecimals(contractID int32, cache map[int32]decimals) (decima
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return decimals{}, fmt.Errorf("can't create script: %v", err)
|
return decimals{}, fmt.Errorf("can't create script: %w", err)
|
||||||
}
|
}
|
||||||
res := s.runScriptInVM(script, nil)
|
res := s.runScriptInVM(script, nil)
|
||||||
if res == nil || res.State != "HALT" || len(res.Stack) == 0 {
|
if res == nil || res.State != "HALT" || len(res.Stack) == 0 {
|
||||||
|
@ -692,7 +692,7 @@ func (s *Server) getrawtransaction(reqParams request.Params) (interface{}, *resp
|
||||||
if txHash, err := reqParams.Value(0).GetUint256(); err != nil {
|
if txHash, err := reqParams.Value(0).GetUint256(); err != nil {
|
||||||
resultsErr = response.ErrInvalidParams
|
resultsErr = response.ErrInvalidParams
|
||||||
} else if tx, height, err := s.chain.GetTransaction(txHash); err != nil {
|
} else if tx, height, err := s.chain.GetTransaction(txHash); err != nil {
|
||||||
err = errors.Wrapf(err, "Invalid transaction hash: %s", txHash)
|
err = fmt.Errorf("invalid transaction %s: %w", txHash, err)
|
||||||
return nil, response.NewRPCError("Unknown transaction", err.Error(), err)
|
return nil, response.NewRPCError("Unknown transaction", err.Error(), err)
|
||||||
} else if reqParams.Value(1).GetBoolean() {
|
} else if reqParams.Value(1).GetBoolean() {
|
||||||
_header := s.chain.GetHeaderHash(int(height))
|
_header := s.chain.GetHeaderHash(int(height))
|
||||||
|
@ -917,8 +917,8 @@ func (s *Server) submitBlock(reqParams request.Params) (interface{}, *response.E
|
||||||
}
|
}
|
||||||
err = s.chain.AddBlock(b)
|
err = s.chain.AddBlock(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err {
|
switch {
|
||||||
case core.ErrInvalidBlockIndex, core.ErrAlreadyExists:
|
case errors.Is(err, core.ErrInvalidBlockIndex) || errors.Is(err, core.ErrAlreadyExists):
|
||||||
return nil, response.ErrAlreadyExists
|
return nil, response.ErrAlreadyExists
|
||||||
default:
|
default:
|
||||||
return nil, response.ErrValidationFailed
|
return nil, response.ErrValidationFailed
|
||||||
|
|
|
@ -95,13 +95,13 @@ func GetVersion(version string) (Version, error) {
|
||||||
}
|
}
|
||||||
major, err := strconv.ParseInt(versions[0], 10, 32)
|
major, err := strconv.ParseInt(versions[0], 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, fmt.Errorf("failed to parse major version: %v", err)
|
return result, fmt.Errorf("failed to parse major version: %w", err)
|
||||||
}
|
}
|
||||||
result.Major = int32(major)
|
result.Major = int32(major)
|
||||||
|
|
||||||
minor, err := strconv.ParseInt(versions[1], 10, 32)
|
minor, err := strconv.ParseInt(versions[1], 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, fmt.Errorf("failed to parse minor version: %v", err)
|
return result, fmt.Errorf("failed to parse minor version: %w", err)
|
||||||
|
|
||||||
}
|
}
|
||||||
result.Minor = int32(minor)
|
result.Minor = int32(minor)
|
||||||
|
@ -112,7 +112,7 @@ func GetVersion(version string) (Version, error) {
|
||||||
}
|
}
|
||||||
build, err := strconv.ParseInt(b, 10, 32)
|
build, err := strconv.ParseInt(b, 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, fmt.Errorf("failed to parse build version: %v", err)
|
return result, fmt.Errorf("failed to parse build version: %w", err)
|
||||||
}
|
}
|
||||||
result.Build = int32(build)
|
result.Build = int32(build)
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ func GetVersion(version string) (Version, error) {
|
||||||
r := strings.SplitN(versions[3], "-", 2)[0]
|
r := strings.SplitN(versions[3], "-", 2)[0]
|
||||||
revision, err := strconv.ParseInt(r, 10, 32)
|
revision, err := strconv.ParseInt(r, 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, fmt.Errorf("failed to parse revision version: %v", err)
|
return result, fmt.Errorf("failed to parse revision version: %w", err)
|
||||||
}
|
}
|
||||||
result.Revision = int32(revision)
|
result.Revision = int32(revision)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package smartcontract
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -10,7 +12,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ParamType represents the Type of the smart contract parameter.
|
// ParamType represents the Type of the smart contract parameter.
|
||||||
|
@ -160,7 +161,7 @@ func ParseParamType(typ string) (ParamType, error) {
|
||||||
case "any":
|
case "any":
|
||||||
return AnyType, nil
|
return AnyType, nil
|
||||||
default:
|
default:
|
||||||
return UnknownType, errors.Errorf("Unknown contract parameter type: %s", typ)
|
return UnknownType, fmt.Errorf("bad parameter type: %s", typ)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
|
@ -14,7 +15,6 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PropertyState represents contract properties (flags).
|
// PropertyState represents contract properties (flags).
|
||||||
|
@ -94,7 +94,7 @@ func (p Parameter) MarshalJSON() ([]byte, error) {
|
||||||
case InteropInterfaceType, AnyType:
|
case InteropInterfaceType, AnyType:
|
||||||
resultRawValue = nil
|
resultRawValue = nil
|
||||||
default:
|
default:
|
||||||
resultErr = errors.Errorf("Marshaller for type %s not implemented", p.Type)
|
resultErr = fmt.Errorf("can't marshal %s", p.Type)
|
||||||
}
|
}
|
||||||
if resultErr != nil {
|
if resultErr != nil {
|
||||||
return nil, resultErr
|
return nil, resultErr
|
||||||
|
@ -183,7 +183,7 @@ func (p *Parameter) UnmarshalJSON(data []byte) (err error) {
|
||||||
// stub, ignore value, it can only be null
|
// stub, ignore value, it can only be null
|
||||||
p.Value = nil
|
p.Value = nil
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("Unmarshaller for type %s not implemented", p.Type)
|
return fmt.Errorf("can't unmarshal %s", p.Type)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -300,7 +300,7 @@ func (p Parameter) TryParse(dest interface{}) error {
|
||||||
switch p.Type {
|
switch p.Type {
|
||||||
case ByteArrayType:
|
case ByteArrayType:
|
||||||
if data, ok = p.Value.([]byte); !ok {
|
if data, ok = p.Value.([]byte); !ok {
|
||||||
return errors.Errorf("failed to cast %s to []byte", p.Value)
|
return fmt.Errorf("failed to cast %s to []byte", p.Value)
|
||||||
}
|
}
|
||||||
switch dest := dest.(type) {
|
switch dest := dest.(type) {
|
||||||
case *util.Uint160:
|
case *util.Uint160:
|
||||||
|
@ -362,7 +362,7 @@ func (p Parameter) TryParse(dest interface{}) error {
|
||||||
*dest = string(data)
|
*dest = string(data)
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("cannot cast param of type %s to type %s", p.Type, dest)
|
return fmt.Errorf("cannot cast param of type %s to type %s", p.Type, dest)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return errors.New("cannot define param type")
|
return errors.New("cannot define param type")
|
||||||
|
@ -373,7 +373,7 @@ func (p Parameter) TryParse(dest interface{}) error {
|
||||||
func bytesToUint64(b []byte, size int) (uint64, error) {
|
func bytesToUint64(b []byte, size int) (uint64, error) {
|
||||||
var length = size / 8
|
var length = size / 8
|
||||||
if len(b) > length {
|
if len(b) > length {
|
||||||
return 0, errors.Errorf("input doesn't fit into %d bits", size)
|
return 0, fmt.Errorf("input doesn't fit into %d bits", size)
|
||||||
}
|
}
|
||||||
if len(b) < length {
|
if len(b) < length {
|
||||||
data := make([]byte, length)
|
data := make([]byte, length)
|
||||||
|
@ -412,7 +412,7 @@ func NewParameterFromString(in string) (*Parameter, error) {
|
||||||
}
|
}
|
||||||
// We currently do not support following types:
|
// We currently do not support following types:
|
||||||
if res.Type == ArrayType || res.Type == MapType || res.Type == InteropInterfaceType || res.Type == VoidType {
|
if res.Type == ArrayType || res.Type == MapType || res.Type == InteropInterfaceType || res.Type == VoidType {
|
||||||
return nil, errors.Errorf("Unsupported contract parameter type: %s", res.Type)
|
return nil, fmt.Errorf("unsupported parameter type %s", res.Type)
|
||||||
}
|
}
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
hadType = true
|
hadType = true
|
||||||
|
|
|
@ -241,7 +241,7 @@ func handleBreak(c *ishell.Context) {
|
||||||
}
|
}
|
||||||
n, err := strconv.Atoi(c.Args[0])
|
n, err := strconv.Atoi(c.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err(fmt.Errorf("argument conversion error: %s", err))
|
c.Err(fmt.Errorf("argument conversion error: %w", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +388,7 @@ func handleStep(c *ishell.Context) {
|
||||||
if len(c.Args) > 0 {
|
if len(c.Args) > 0 {
|
||||||
n, err = strconv.Atoi(c.Args[0])
|
n, err = strconv.Atoi(c.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err(fmt.Errorf("argument conversion error: %s", err))
|
c.Err(fmt.Errorf("argument conversion error: %w", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ func EnumeratorCreate(v *VM) error {
|
||||||
default:
|
default:
|
||||||
data, err := t.TryBytes()
|
data, err := t.TryBytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can not create enumerator from type %s: %v", t.Type(), err)
|
return fmt.Errorf("can not create enumerator from type %s: %w", t.Type(), err)
|
||||||
}
|
}
|
||||||
interop = &byteArrayWrapper{
|
interop = &byteArrayWrapper{
|
||||||
index: -1,
|
index: -1,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
@ -19,7 +20,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -437,7 +437,7 @@ func (v *vmUTStackItem) UnmarshalJSON(data []byte) error {
|
||||||
|
|
||||||
var it vmUTStackItem
|
var it vmUTStackItem
|
||||||
if err := d.Decode(&it); err != nil {
|
if err := d.Decode(&it); err != nil {
|
||||||
return fmt.Errorf("can't decode map value: %v", err)
|
return fmt.Errorf("can't decode map value: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
item := jsonStringToInteger(key)
|
item := jsonStringToInteger(key)
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// State of the VM.
|
// State of the VM.
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math"
|
"math"
|
||||||
|
@ -20,7 +21,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type errorAtInstruct struct {
|
type errorAtInstruct struct {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
@ -17,7 +18,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
|
@ -55,11 +55,11 @@ func (d dump) normalize() {
|
||||||
func compare(a, b string) error {
|
func compare(a, b string) error {
|
||||||
dumpA, err := readFile(a)
|
dumpA, err := readFile(a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("reading file %s: %v", a, err)
|
return fmt.Errorf("reading file %s: %w", a, err)
|
||||||
}
|
}
|
||||||
dumpB, err := readFile(b)
|
dumpB, err := readFile(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("reading file %s: %v", b, err)
|
return fmt.Errorf("reading file %s: %w", b, err)
|
||||||
}
|
}
|
||||||
dumpA.normalize()
|
dumpA.normalize()
|
||||||
dumpB.normalize()
|
dumpB.normalize()
|
||||||
|
@ -143,7 +143,7 @@ func cliMain(c *cli.Context) error {
|
||||||
bname := filepath.Join(b, fname)
|
bname := filepath.Join(b, fname)
|
||||||
err := compare(aname, bname)
|
err := compare(aname, bname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("file %s: %v", fname, err)
|
return fmt.Errorf("file %s: %w", fname, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue