forked from TrueCloudLab/neoneo-go
rpc: add test for submitNotaryRequest
This commit is contained in:
parent
af510b4e25
commit
a237e34c1f
6 changed files with 325 additions and 17 deletions
|
@ -8,6 +8,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -25,6 +26,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
|
@ -296,9 +298,11 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
|
||||||
gasHash := bc.contracts.GAS.Hash
|
gasHash := bc.contracts.GAS.Hash
|
||||||
neoHash := bc.contracts.NEO.Hash
|
neoHash := bc.contracts.NEO.Hash
|
||||||
policyHash := bc.contracts.Policy.Hash
|
policyHash := bc.contracts.Policy.Hash
|
||||||
|
notaryHash := bc.contracts.Notary.Hash
|
||||||
t.Logf("native GAS hash: %v", gasHash)
|
t.Logf("native GAS hash: %v", gasHash)
|
||||||
t.Logf("native NEO hash: %v", neoHash)
|
t.Logf("native NEO hash: %v", neoHash)
|
||||||
t.Logf("native Policy hash: %v", policyHash)
|
t.Logf("native Policy hash: %v", policyHash)
|
||||||
|
t.Logf("native Notary hash: %v", notaryHash)
|
||||||
|
|
||||||
priv0 := testchain.PrivateKeyByID(0)
|
priv0 := testchain.PrivateKeyByID(0)
|
||||||
priv0ScriptHash := priv0.GetScriptHash()
|
priv0ScriptHash := priv0.GetScriptHash()
|
||||||
|
@ -426,6 +430,31 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
|
||||||
require.NoError(t, acc0.SignTx(txDeploy2))
|
require.NoError(t, acc0.SignTx(txDeploy2))
|
||||||
b = bc.newBlock(txDeploy2)
|
b = bc.newBlock(txDeploy2)
|
||||||
require.NoError(t, bc.AddBlock(b))
|
require.NoError(t, bc.AddBlock(b))
|
||||||
|
|
||||||
|
// Deposit some GAS to notary contract for priv0
|
||||||
|
transferTx = newNEP17Transfer(gasHash, priv0.GetScriptHash(), notaryHash, 10_0000_0000, priv0.GetScriptHash(), int64(bc.BlockHeight()+1000))
|
||||||
|
transferTx.Nonce = getNextNonce()
|
||||||
|
transferTx.ValidUntilBlock = validUntilBlock
|
||||||
|
transferTx.Signers = []transaction.Signer{
|
||||||
|
{
|
||||||
|
Account: priv0ScriptHash,
|
||||||
|
Scopes: transaction.CalledByEntry,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
require.NoError(t, addNetworkFee(bc, transferTx, acc0))
|
||||||
|
transferTx.SystemFee += 10_0000
|
||||||
|
require.NoError(t, acc0.SignTx(transferTx))
|
||||||
|
|
||||||
|
b = bc.newBlock(transferTx)
|
||||||
|
require.NoError(t, bc.AddBlock(b))
|
||||||
|
t.Logf("notaryDepositTxPriv0: %v", transferTx.Hash().StringLE())
|
||||||
|
|
||||||
|
// Designate new Notary node
|
||||||
|
ntr, err := wallet.NewWalletFromFile(path.Join(notaryModulePath, "./testdata/notary1.json"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, ntr.Accounts[0].Decrypt("one"))
|
||||||
|
bc.setNodesByRole(t, true, native.RoleP2PNotary, keys.PublicKeys{ntr.Accounts[0].PrivateKey().PublicKey()})
|
||||||
|
t.Logf("Designated Notary node: %s", hex.EncodeToString(ntr.Accounts[0].PrivateKey().PublicKey().Bytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNEP17Transfer(sc, from, to util.Uint160, amount int64, additionalArgs ...interface{}) *transaction.Transaction {
|
func newNEP17Transfer(sc, from, to util.Uint160, amount int64, additionalArgs ...interface{}) *transaction.Transaction {
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/network/payload"
|
"github.com/nspcc-dev/neo-go/pkg/network/payload"
|
||||||
"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/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"go.uber.org/atomic"
|
"go.uber.org/atomic"
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/internal/testchain"
|
"github.com/nspcc-dev/neo-go/internal/testchain"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/fee"
|
"github.com/nspcc-dev/neo-go/pkg/core/fee"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
|
@ -17,6 +18,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||||
"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"
|
||||||
"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/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -214,6 +216,111 @@ func TestSignAndPushInvocationTx(t *testing.T) {
|
||||||
require.EqualValues(t, 30, tx.SystemFee)
|
require.EqualValues(t, 30, tx.SystemFee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSignAndPushP2PNotaryRequest(t *testing.T) {
|
||||||
|
chain, rpcSrv, httpSrv := initServerWithInMemoryChainAndServices(t, false, true)
|
||||||
|
defer chain.Close()
|
||||||
|
defer rpcSrv.Shutdown()
|
||||||
|
|
||||||
|
c, err := client.New(context.Background(), httpSrv.URL, client.Options{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
t.Run("client wasn't initialized", func(t *testing.T) {
|
||||||
|
_, err := c.SignAndPushP2PNotaryRequest(nil, nil, 0, 0, 0, nil)
|
||||||
|
require.NotNil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
require.NoError(t, c.Init())
|
||||||
|
t.Run("bad account address", func(t *testing.T) {
|
||||||
|
_, err := c.SignAndPushP2PNotaryRequest(nil, nil, 0, 0, 0, &wallet.Account{Address: "not-an-addr"})
|
||||||
|
require.NotNil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
acc, err := wallet.NewAccount()
|
||||||
|
require.NoError(t, err)
|
||||||
|
t.Run("bad fallback script", func(t *testing.T) {
|
||||||
|
_, err := c.SignAndPushP2PNotaryRequest(nil, []byte{byte(opcode.ASSERT)}, -1, 0, 0, acc)
|
||||||
|
require.NotNil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("too large fallbackValidFor", func(t *testing.T) {
|
||||||
|
_, err := c.SignAndPushP2PNotaryRequest(nil, []byte{byte(opcode.RET)}, -1, 0, 141, acc)
|
||||||
|
require.NotNil(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("good", func(t *testing.T) {
|
||||||
|
sender := testchain.PrivateKeyByID(0) // owner of the deposit in testchain
|
||||||
|
acc := wallet.NewAccountFromPrivateKey(sender)
|
||||||
|
expected := transaction.Transaction{
|
||||||
|
Network: netmode.UnitTestNet,
|
||||||
|
Attributes: []transaction.Attribute{{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}}},
|
||||||
|
Script: []byte{byte(opcode.RET)},
|
||||||
|
ValidUntilBlock: chain.BlockHeight() + 5,
|
||||||
|
Signers: []transaction.Signer{{Account: util.Uint160{1, 5, 9}}},
|
||||||
|
Scripts: []transaction.Witness{{
|
||||||
|
InvocationScript: []byte{1, 4, 7},
|
||||||
|
VerificationScript: []byte{3, 6, 9},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
mainTx := expected
|
||||||
|
_ = expected.Hash()
|
||||||
|
req, err := c.SignAndPushP2PNotaryRequest(&mainTx, []byte{byte(opcode.RET)}, -1, 0, 6, acc)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// check that request was correctly completed
|
||||||
|
require.Equal(t, expected, *req.MainTransaction) // main tx should be the same
|
||||||
|
require.ElementsMatch(t, []transaction.Attribute{
|
||||||
|
{
|
||||||
|
Type: transaction.NotaryAssistedT,
|
||||||
|
Value: &transaction.NotaryAssisted{NKeys: 0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: transaction.NotValidBeforeT,
|
||||||
|
Value: &transaction.NotValidBefore{Height: chain.BlockHeight()},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: transaction.ConflictsT,
|
||||||
|
Value: &transaction.Conflicts{Hash: mainTx.Hash()},
|
||||||
|
},
|
||||||
|
}, req.FallbackTransaction.Attributes)
|
||||||
|
require.Equal(t, []transaction.Signer{
|
||||||
|
{Account: chain.GetNotaryContractScriptHash()},
|
||||||
|
{Account: acc.PrivateKey().GetScriptHash()},
|
||||||
|
}, req.FallbackTransaction.Signers)
|
||||||
|
|
||||||
|
// it shouldn't be an error to add completed fallback to the chain
|
||||||
|
w, err := wallet.NewWalletFromFile(notaryPath)
|
||||||
|
require.NoError(t, err)
|
||||||
|
ntr := w.Accounts[0]
|
||||||
|
ntr.Decrypt(notaryPass)
|
||||||
|
req.FallbackTransaction.Scripts[0] = transaction.Witness{
|
||||||
|
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, ntr.PrivateKey().Sign(req.FallbackTransaction.GetSignedPart())...),
|
||||||
|
VerificationScript: []byte{},
|
||||||
|
}
|
||||||
|
b := testchain.NewBlock(t, chain, 1, 0, req.FallbackTransaction)
|
||||||
|
require.NoError(t, chain.AddBlock(b))
|
||||||
|
appLogs, err := chain.GetAppExecResults(req.FallbackTransaction.Hash(), trigger.Application)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(appLogs))
|
||||||
|
appLog := appLogs[0]
|
||||||
|
require.Equal(t, vm.HaltState, appLog.VMState)
|
||||||
|
require.Equal(t, appLog.GasConsumed, req.FallbackTransaction.SystemFee)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCalculateNotaryFee(t *testing.T) {
|
||||||
|
chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t)
|
||||||
|
defer chain.Close()
|
||||||
|
defer rpcSrv.Shutdown()
|
||||||
|
|
||||||
|
c, err := client.New(context.Background(), httpSrv.URL, client.Options{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
t.Run("client not initialized", func(t *testing.T) {
|
||||||
|
_, err := c.CalculateNotaryFee(0)
|
||||||
|
require.NotNil(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestPing(t *testing.T) {
|
func TestPing(t *testing.T) {
|
||||||
chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t)
|
chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t)
|
||||||
defer chain.Close()
|
defer chain.Close()
|
||||||
|
|
|
@ -23,7 +23,12 @@ import (
|
||||||
"go.uber.org/zap/zaptest"
|
"go.uber.org/zap/zaptest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getUnitTestChain(t *testing.T, enableOracle bool) (*core.Blockchain, *oracle.Oracle, config.Config, *zap.Logger) {
|
const (
|
||||||
|
notaryPath = "../../services/notary/testdata/notary1.json"
|
||||||
|
notaryPass = "one"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getUnitTestChain(t *testing.T, enableOracle bool, enableNotary bool) (*core.Blockchain, *oracle.Oracle, config.Config, *zap.Logger) {
|
||||||
net := netmode.UnitTestNet
|
net := netmode.UnitTestNet
|
||||||
configPath := "../../../config"
|
configPath := "../../../config"
|
||||||
cfg, err := config.Load(configPath, net)
|
cfg, err := config.Load(configPath, net)
|
||||||
|
@ -31,6 +36,19 @@ func getUnitTestChain(t *testing.T, enableOracle bool) (*core.Blockchain, *oracl
|
||||||
|
|
||||||
memoryStore := storage.NewMemoryStore()
|
memoryStore := storage.NewMemoryStore()
|
||||||
logger := zaptest.NewLogger(t)
|
logger := zaptest.NewLogger(t)
|
||||||
|
if enableNotary {
|
||||||
|
cfg.ProtocolConfiguration.P2PSigExtensions = true
|
||||||
|
cfg.ProtocolConfiguration.P2PNotaryRequestPayloadPoolSize = 1000
|
||||||
|
cfg.ProtocolConfiguration.P2PNotary = config.P2PNotary{
|
||||||
|
Enabled: true,
|
||||||
|
UnlockWallet: config.Wallet{
|
||||||
|
Path: notaryPath,
|
||||||
|
Password: notaryPass,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cfg.ProtocolConfiguration.P2PNotary.Enabled = false
|
||||||
|
}
|
||||||
chain, err := core.NewBlockchain(memoryStore, cfg.ProtocolConfiguration, logger)
|
chain, err := core.NewBlockchain(memoryStore, cfg.ProtocolConfiguration, logger)
|
||||||
require.NoError(t, err, "could not create chain")
|
require.NoError(t, err, "could not create chain")
|
||||||
|
|
||||||
|
@ -79,8 +97,8 @@ func getTestBlocks(t *testing.T) []*block.Block {
|
||||||
return blocks
|
return blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
func initClearServerWithOracle(t *testing.T, needOracle bool) (*core.Blockchain, *Server, *httptest.Server) {
|
func initClearServerWithServices(t *testing.T, needOracle bool, needNotary bool) (*core.Blockchain, *Server, *httptest.Server) {
|
||||||
chain, orc, cfg, logger := getUnitTestChain(t, needOracle)
|
chain, orc, cfg, logger := getUnitTestChain(t, needOracle, needNotary)
|
||||||
|
|
||||||
serverConfig := network.NewServerConfig(cfg)
|
serverConfig := network.NewServerConfig(cfg)
|
||||||
server, err := network.NewServer(serverConfig, chain, logger)
|
server, err := network.NewServer(serverConfig, chain, logger)
|
||||||
|
@ -96,7 +114,7 @@ func initClearServerWithOracle(t *testing.T, needOracle bool) (*core.Blockchain,
|
||||||
}
|
}
|
||||||
|
|
||||||
func initClearServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *httptest.Server) {
|
func initClearServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *httptest.Server) {
|
||||||
return initClearServerWithOracle(t, false)
|
return initClearServerWithServices(t, false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *httptest.Server) {
|
func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *httptest.Server) {
|
||||||
|
@ -108,6 +126,15 @@ func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *http
|
||||||
return chain, rpcServer, srv
|
return chain, rpcServer, srv
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initServerWithInMemoryChainAndServices(t *testing.T, needOracle bool, needNotary bool) (*core.Blockchain, *Server, *httptest.Server) {
|
||||||
|
chain, rpcServer, srv := initClearServerWithServices(t, needOracle, needNotary)
|
||||||
|
|
||||||
|
for _, b := range getTestBlocks(t) {
|
||||||
|
require.NoError(t, chain.AddBlock(b))
|
||||||
|
}
|
||||||
|
return chain, rpcServer, srv
|
||||||
|
}
|
||||||
|
|
||||||
type FeerStub struct{}
|
type FeerStub struct{}
|
||||||
|
|
||||||
func (fs *FeerStub) FeePerByte() int64 {
|
func (fs *FeerStub) FeePerByte() int64 {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/nspcc-dev/neo-go/internal/testchain"
|
"github.com/nspcc-dev/neo-go/internal/testchain"
|
||||||
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
"github.com/nspcc-dev/neo-go/pkg/core"
|
||||||
"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/core/fee"
|
"github.com/nspcc-dev/neo-go/pkg/core/fee"
|
||||||
|
@ -27,6 +28,7 @@ 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/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/network/payload"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response"
|
"github.com/nspcc-dev/neo-go/pkg/rpc/response"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result"
|
||||||
rpc2 "github.com/nspcc-dev/neo-go/pkg/services/oracle/broadcaster"
|
rpc2 "github.com/nspcc-dev/neo-go/pkg/services/oracle/broadcaster"
|
||||||
|
@ -58,7 +60,7 @@ type rpcTestCase struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
const testContractHash = "c6436aab21ebd15279b85af8d7b5808d38455b0a"
|
const testContractHash = "c6436aab21ebd15279b85af8d7b5808d38455b0a"
|
||||||
const deploymentTxHash = "9a9d6b0876d1e6cfd68efadd0facaaba7e07efbe7b24282d094a0893645581f3"
|
const deploymentTxHash = "d0de42d5d23211174a50d74fbd4a919631236a63f16431a5a7e7126759e7ba23"
|
||||||
const genesisBlockHash = "0542f4350c6e236d0509bcd98188b0034bfbecc1a0c7fcdb8e4295310d468b70"
|
const genesisBlockHash = "0542f4350c6e236d0509bcd98188b0034bfbecc1a0c7fcdb8e4295310d468b70"
|
||||||
|
|
||||||
const verifyContractHash = "03ffc0897543b9b709e0f8cab4a7682dae0ba943"
|
const verifyContractHash = "03ffc0897543b9b709e0f8cab4a7682dae0ba943"
|
||||||
|
@ -649,7 +651,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
expected := result.UnclaimedGas{
|
expected := result.UnclaimedGas{
|
||||||
Address: testchain.MultisigScriptHash(),
|
Address: testchain.MultisigScriptHash(),
|
||||||
Unclaimed: *big.NewInt(3500),
|
Unclaimed: *big.NewInt(4500),
|
||||||
}
|
}
|
||||||
assert.Equal(t, expected, *actual)
|
assert.Equal(t, expected, *actual)
|
||||||
},
|
},
|
||||||
|
@ -918,6 +920,13 @@ var rpcTestCases = map[string][]rpcTestCase{
|
||||||
fail: true,
|
fail: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"submitnotaryrequest": {
|
||||||
|
{
|
||||||
|
name: "no params",
|
||||||
|
params: `[]`,
|
||||||
|
fail: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
"validateaddress": {
|
"validateaddress": {
|
||||||
{
|
{
|
||||||
name: "positive",
|
name: "positive",
|
||||||
|
@ -954,7 +963,7 @@ func TestRPC(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSubmitOracle(t *testing.T) {
|
func TestSubmitOracle(t *testing.T) {
|
||||||
chain, rpcSrv, httpSrv := initClearServerWithOracle(t, true)
|
chain, rpcSrv, httpSrv := initClearServerWithServices(t, true, false)
|
||||||
defer chain.Close()
|
defer chain.Close()
|
||||||
defer rpcSrv.Shutdown()
|
defer rpcSrv.Shutdown()
|
||||||
|
|
||||||
|
@ -986,6 +995,121 @@ func TestSubmitOracle(t *testing.T) {
|
||||||
t.Run("Valid", runCase(t, false, pubStr, `1`, txSigStr, msgSigStr))
|
t.Run("Valid", runCase(t, false, pubStr, `1`, txSigStr, msgSigStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSubmitNotaryRequest(t *testing.T) {
|
||||||
|
rpc := `{"jsonrpc": "2.0", "id": 1, "method": "submitnotaryrequest", "params": %s}`
|
||||||
|
|
||||||
|
t.Run("disabled P2PSigExtensions", func(t *testing.T) {
|
||||||
|
chain, rpcSrv, httpSrv := initClearServerWithServices(t, false, false)
|
||||||
|
defer chain.Close()
|
||||||
|
defer rpcSrv.Shutdown()
|
||||||
|
req := fmt.Sprintf(rpc, "[]")
|
||||||
|
body := doRPCCallOverHTTP(req, httpSrv.URL, t)
|
||||||
|
checkErrGetResult(t, body, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
chain, rpcSrv, httpSrv := initServerWithInMemoryChainAndServices(t, false, true)
|
||||||
|
defer chain.Close()
|
||||||
|
defer rpcSrv.Shutdown()
|
||||||
|
|
||||||
|
runCase := func(t *testing.T, fail bool, params ...string) func(t *testing.T) {
|
||||||
|
return func(t *testing.T) {
|
||||||
|
ps := `[` + strings.Join(params, ",") + `]`
|
||||||
|
req := fmt.Sprintf(rpc, ps)
|
||||||
|
body := doRPCCallOverHTTP(req, httpSrv.URL, t)
|
||||||
|
checkErrGetResult(t, body, fail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.Run("missing request", runCase(t, true))
|
||||||
|
t.Run("not a base64", runCase(t, true, `"not-a-base64$"`))
|
||||||
|
t.Run("invalid request bytes", runCase(t, true, `"not-a-request"`))
|
||||||
|
t.Run("invalid request", func(t *testing.T) {
|
||||||
|
mainTx := &transaction.Transaction{
|
||||||
|
Network: netmode.UnitTestNet,
|
||||||
|
Attributes: []transaction.Attribute{{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}}},
|
||||||
|
Script: []byte{byte(opcode.RET)},
|
||||||
|
ValidUntilBlock: 123,
|
||||||
|
Signers: []transaction.Signer{{Account: util.Uint160{1, 5, 9}}},
|
||||||
|
Scripts: []transaction.Witness{{
|
||||||
|
InvocationScript: []byte{1, 4, 7},
|
||||||
|
VerificationScript: []byte{3, 6, 9},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
fallbackTx := &transaction.Transaction{
|
||||||
|
Network: netmode.UnitTestNet,
|
||||||
|
Script: []byte{byte(opcode.RET)},
|
||||||
|
ValidUntilBlock: 123,
|
||||||
|
Attributes: []transaction.Attribute{
|
||||||
|
{Type: transaction.NotValidBeforeT, Value: &transaction.NotValidBefore{Height: 123}},
|
||||||
|
{Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: mainTx.Hash()}},
|
||||||
|
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}},
|
||||||
|
},
|
||||||
|
Signers: []transaction.Signer{{Account: util.Uint160{1, 4, 7}}, {Account: util.Uint160{9, 8, 7}}},
|
||||||
|
Scripts: []transaction.Witness{
|
||||||
|
{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: make([]byte, 0)},
|
||||||
|
{InvocationScript: []byte{1, 2, 3}, VerificationScript: []byte{1, 2, 3}}},
|
||||||
|
}
|
||||||
|
p := &payload.P2PNotaryRequest{
|
||||||
|
Network: netmode.UnitTestNet,
|
||||||
|
MainTransaction: mainTx,
|
||||||
|
FallbackTransaction: fallbackTx,
|
||||||
|
Witness: transaction.Witness{
|
||||||
|
InvocationScript: []byte{1, 2, 3},
|
||||||
|
VerificationScript: []byte{7, 8, 9},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
bytes, err := p.Bytes()
|
||||||
|
require.NoError(t, err)
|
||||||
|
str := fmt.Sprintf(`"%s"`, base64.StdEncoding.EncodeToString(bytes))
|
||||||
|
runCase(t, true, str)(t)
|
||||||
|
})
|
||||||
|
t.Run("valid request", func(t *testing.T) {
|
||||||
|
sender := testchain.PrivateKeyByID(0) // owner of the deposit in testchain
|
||||||
|
mainTx := &transaction.Transaction{
|
||||||
|
Network: netmode.UnitTestNet,
|
||||||
|
Attributes: []transaction.Attribute{{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}}},
|
||||||
|
Script: []byte{byte(opcode.RET)},
|
||||||
|
ValidUntilBlock: 123,
|
||||||
|
Signers: []transaction.Signer{{Account: util.Uint160{1, 5, 9}}},
|
||||||
|
Scripts: []transaction.Witness{{
|
||||||
|
InvocationScript: []byte{1, 4, 7},
|
||||||
|
VerificationScript: []byte{3, 6, 9},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
fallbackTx := &transaction.Transaction{
|
||||||
|
Network: netmode.UnitTestNet,
|
||||||
|
Script: []byte{byte(opcode.RET)},
|
||||||
|
ValidUntilBlock: 123,
|
||||||
|
Attributes: []transaction.Attribute{
|
||||||
|
{Type: transaction.NotValidBeforeT, Value: &transaction.NotValidBefore{Height: 123}},
|
||||||
|
{Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: mainTx.Hash()}},
|
||||||
|
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}},
|
||||||
|
},
|
||||||
|
Signers: []transaction.Signer{{Account: chain.GetNotaryContractScriptHash()}, {Account: sender.GetScriptHash()}},
|
||||||
|
Scripts: []transaction.Witness{
|
||||||
|
{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, make([]byte, 64, 64)...), VerificationScript: []byte{}},
|
||||||
|
},
|
||||||
|
NetworkFee: 2_0000_0000,
|
||||||
|
}
|
||||||
|
fallbackTx.Scripts = append(fallbackTx.Scripts, transaction.Witness{
|
||||||
|
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, sender.Sign(fallbackTx.GetSignedPart())...),
|
||||||
|
VerificationScript: sender.PublicKey().GetVerificationScript(),
|
||||||
|
})
|
||||||
|
p := &payload.P2PNotaryRequest{
|
||||||
|
Network: netmode.UnitTestNet,
|
||||||
|
MainTransaction: mainTx,
|
||||||
|
FallbackTransaction: fallbackTx,
|
||||||
|
}
|
||||||
|
p.Witness = transaction.Witness{
|
||||||
|
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), 64}, sender.Sign(p.GetSignedPart())...),
|
||||||
|
VerificationScript: sender.PublicKey().GetVerificationScript(),
|
||||||
|
}
|
||||||
|
bytes, err := p.Bytes()
|
||||||
|
require.NoError(t, err)
|
||||||
|
str := fmt.Sprintf(`"%s"`, base64.StdEncoding.EncodeToString(bytes))
|
||||||
|
runCase(t, false, str)(t)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// testRPCProtocol runs a full set of tests using given callback to make actual
|
// testRPCProtocol runs a full set of tests using given callback to make actual
|
||||||
// calls. Some tests change the chain state, thus we reinitialize the chain from
|
// calls. Some tests change the chain state, thus we reinitialize the chain from
|
||||||
// scratch here.
|
// scratch here.
|
||||||
|
@ -1246,7 +1370,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
|
||||||
require.NoErrorf(t, err, "could not parse response: %s", txOut)
|
require.NoErrorf(t, err, "could not parse response: %s", txOut)
|
||||||
|
|
||||||
assert.Equal(t, *block.Transactions[0], actual.Transaction)
|
assert.Equal(t, *block.Transactions[0], actual.Transaction)
|
||||||
assert.Equal(t, 8, actual.Confirmations)
|
assert.Equal(t, 10, actual.Confirmations)
|
||||||
assert.Equal(t, TXHash, actual.Transaction.Hash())
|
assert.Equal(t, TXHash, actual.Transaction.Hash())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1364,12 +1488,12 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
|
||||||
require.NoError(t, json.Unmarshal(res, actual))
|
require.NoError(t, json.Unmarshal(res, actual))
|
||||||
checkNep17TransfersAux(t, e, actual, sent, rcvd)
|
checkNep17TransfersAux(t, e, actual, sent, rcvd)
|
||||||
}
|
}
|
||||||
t.Run("time frame only", func(t *testing.T) { testNEP17T(t, 4, 5, 0, 0, []int{3, 4, 5, 6}, []int{1, 2}) })
|
t.Run("time frame only", func(t *testing.T) { testNEP17T(t, 4, 5, 0, 0, []int{5, 6, 7, 8}, []int{1, 2}) })
|
||||||
t.Run("no res", func(t *testing.T) { testNEP17T(t, 100, 100, 0, 0, []int{}, []int{}) })
|
t.Run("no res", func(t *testing.T) { testNEP17T(t, 100, 100, 0, 0, []int{}, []int{}) })
|
||||||
t.Run("limit", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 0, []int{0, 1}, []int{0}) })
|
t.Run("limit", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 0, []int{2, 3}, []int{0}) })
|
||||||
t.Run("limit 2", func(t *testing.T) { testNEP17T(t, 4, 5, 2, 0, []int{3}, []int{1}) })
|
t.Run("limit 2", func(t *testing.T) { testNEP17T(t, 4, 5, 2, 0, []int{5}, []int{1}) })
|
||||||
t.Run("limit with page", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 1, []int{2, 3}, []int{1}) })
|
t.Run("limit with page", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 1, []int{4, 5}, []int{1}) })
|
||||||
t.Run("limit with page 2", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 2, []int{4, 5}, []int{2}) })
|
t.Run("limit with page 2", func(t *testing.T) { testNEP17T(t, 1, 7, 3, 2, []int{6, 7}, []int{2}) })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1474,8 +1598,8 @@ func checkNep17Balances(t *testing.T, e *executor, acc interface{}) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Asset: e.chain.UtilityTokenHash(),
|
Asset: e.chain.UtilityTokenHash(),
|
||||||
Amount: "80006665650",
|
Amount: "78994306100",
|
||||||
LastUpdated: 7,
|
LastUpdated: 8,
|
||||||
}},
|
}},
|
||||||
Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(),
|
Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(),
|
||||||
}
|
}
|
||||||
|
@ -1484,7 +1608,7 @@ func checkNep17Balances(t *testing.T, e *executor, acc interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkNep17Transfers(t *testing.T, e *executor, acc interface{}) {
|
func checkNep17Transfers(t *testing.T, e *executor, acc interface{}) {
|
||||||
checkNep17TransfersAux(t, e, acc, []int{0, 1, 2, 3, 4, 5, 6, 7, 8}, []int{0, 1, 2, 3, 4, 5, 6})
|
checkNep17TransfersAux(t, e, acc, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, []int{0, 1, 2, 3, 4, 5, 6})
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkNep17TransfersAux(t *testing.T, e *executor, acc interface{}, sent, rcvd []int) {
|
func checkNep17TransfersAux(t *testing.T, e *executor, acc interface{}, sent, rcvd []int) {
|
||||||
|
@ -1493,6 +1617,11 @@ func checkNep17TransfersAux(t *testing.T, e *executor, acc interface{}, sent, rc
|
||||||
rublesHash, err := util.Uint160DecodeStringLE(testContractHash)
|
rublesHash, err := util.Uint160DecodeStringLE(testContractHash)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
blockDepositGAS, err := e.chain.GetBlock(e.chain.GetHeaderHash(8))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(blockDepositGAS.Transactions))
|
||||||
|
txDepositGAS := blockDepositGAS.Transactions[0]
|
||||||
|
|
||||||
blockDeploy2, err := e.chain.GetBlock(e.chain.GetHeaderHash(7))
|
blockDeploy2, err := e.chain.GetBlock(e.chain.GetHeaderHash(7))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 1, len(blockDeploy2.Transactions))
|
require.Equal(t, 1, len(blockDeploy2.Transactions))
|
||||||
|
@ -1541,6 +1670,23 @@ func checkNep17TransfersAux(t *testing.T, e *executor, acc interface{}, sent, rc
|
||||||
// duplicate the Server method.
|
// duplicate the Server method.
|
||||||
expected := result.NEP17Transfers{
|
expected := result.NEP17Transfers{
|
||||||
Sent: []result.NEP17Transfer{
|
Sent: []result.NEP17Transfer{
|
||||||
|
{
|
||||||
|
Timestamp: blockDepositGAS.Timestamp,
|
||||||
|
Asset: e.chain.UtilityTokenHash(),
|
||||||
|
Address: address.Uint160ToString(e.chain.GetNotaryContractScriptHash()),
|
||||||
|
Amount: "1000000000",
|
||||||
|
Index: 8,
|
||||||
|
NotifyIndex: 0,
|
||||||
|
TxHash: txDepositGAS.Hash(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Timestamp: blockDepositGAS.Timestamp,
|
||||||
|
Asset: e.chain.UtilityTokenHash(),
|
||||||
|
Address: "", // burn
|
||||||
|
Amount: big.NewInt(txDepositGAS.SystemFee + txDepositGAS.NetworkFee).String(),
|
||||||
|
Index: 8,
|
||||||
|
TxHash: blockDepositGAS.Hash(),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Timestamp: blockDeploy2.Timestamp,
|
Timestamp: blockDeploy2.Timestamp,
|
||||||
Asset: e.chain.UtilityTokenHash(),
|
Asset: e.chain.UtilityTokenHash(),
|
||||||
|
|
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
Binary file not shown.
Loading…
Reference in a new issue