forked from TrueCloudLab/neoneo-go
Merge pull request #1300 from nspcc-dev/various-preview3-fixes
Various preview3 testnet fixes
This commit is contained in:
commit
25ce154cf8
15 changed files with 89 additions and 100 deletions
|
@ -25,42 +25,6 @@ type storageOp struct {
|
||||||
Value string `json:"value,omitempty"`
|
Value string `json:"value,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NEO has some differences of key storing (that should go away post-preview2).
|
|
||||||
// ours format: contract's ID (uint32le) + key
|
|
||||||
// theirs format: contract's ID (uint32le) + key with 16 between every 16 bytes, padded to len 16.
|
|
||||||
func toNeoStorageKey(key []byte) []byte {
|
|
||||||
if len(key) < 4 {
|
|
||||||
panic("invalid key in storage")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prefix is a contract's ID in LE.
|
|
||||||
nkey := make([]byte, 4, len(key))
|
|
||||||
copy(nkey, key[:4])
|
|
||||||
key = key[4:]
|
|
||||||
|
|
||||||
index := 0
|
|
||||||
remain := len(key)
|
|
||||||
for remain >= 16 {
|
|
||||||
nkey = append(nkey, key[index:index+16]...)
|
|
||||||
nkey = append(nkey, 16)
|
|
||||||
index += 16
|
|
||||||
remain -= 16
|
|
||||||
}
|
|
||||||
|
|
||||||
if remain > 0 {
|
|
||||||
nkey = append(nkey, key[index:]...)
|
|
||||||
}
|
|
||||||
|
|
||||||
padding := 16 - remain
|
|
||||||
for i := 0; i < padding; i++ {
|
|
||||||
nkey = append(nkey, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
nkey = append(nkey, byte(remain))
|
|
||||||
|
|
||||||
return nkey
|
|
||||||
}
|
|
||||||
|
|
||||||
// batchToMap converts batch to a map so that JSON is compatible
|
// batchToMap converts batch to a map so that JSON is compatible
|
||||||
// with https://github.com/NeoResearch/neo-storage-audit/
|
// with https://github.com/NeoResearch/neo-storage-audit/
|
||||||
func batchToMap(index uint32, batch *storage.MemBatch) blockDump {
|
func batchToMap(index uint32, batch *storage.MemBatch) blockDump {
|
||||||
|
@ -77,10 +41,9 @@ func batchToMap(index uint32, batch *storage.MemBatch) blockDump {
|
||||||
op = "Changed"
|
op = "Changed"
|
||||||
}
|
}
|
||||||
|
|
||||||
key = toNeoStorageKey(key[1:])
|
|
||||||
ops = append(ops, storageOp{
|
ops = append(ops, storageOp{
|
||||||
State: op,
|
State: op,
|
||||||
Key: hex.EncodeToString(key),
|
Key: hex.EncodeToString(key[1:]),
|
||||||
Value: hex.EncodeToString(batch.Put[i].Value),
|
Value: hex.EncodeToString(batch.Put[i].Value),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -91,10 +54,9 @@ func batchToMap(index uint32, batch *storage.MemBatch) blockDump {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
key = toNeoStorageKey(key[1:])
|
|
||||||
ops = append(ops, storageOp{
|
ops = append(ops, storageOp{
|
||||||
State: "Deleted",
|
State: "Deleted",
|
||||||
Key: hex.EncodeToString(key),
|
Key: hex.EncodeToString(key[1:]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -518,7 +518,7 @@ func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
script, err := smartcontract.CreateMultiSigRedeemScript(len(validators)-(len(validators)-1)/3, validators)
|
script, err := smartcontract.CreateMultiSigRedeemScript(s.dbft.Context.M(), validators)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,7 +226,7 @@ func newTestService(t *testing.T) *service {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTestValidator(i int) (*privateKey, *publicKey) {
|
func getTestValidator(i int) (*privateKey, *publicKey) {
|
||||||
key := testchain.PrivateKeyByID(i)
|
key := testchain.PrivateKey(i)
|
||||||
return &privateKey{PrivateKey: key}, &publicKey{PublicKey: key.PublicKey()}
|
return &privateKey{PrivateKey: key}, &publicKey{PublicKey: key.PublicKey()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,11 +51,7 @@ func (bc *Blockchain) newBlock(txs ...*transaction.Transaction) *block.Block {
|
||||||
|
|
||||||
func newBlock(cfg config.ProtocolConfiguration, index uint32, prev util.Uint256, txs ...*transaction.Transaction) *block.Block {
|
func newBlock(cfg config.ProtocolConfiguration, index uint32, prev util.Uint256, txs ...*transaction.Transaction) *block.Block {
|
||||||
validators, _ := validatorsFromConfig(cfg)
|
validators, _ := validatorsFromConfig(cfg)
|
||||||
vlen := len(validators)
|
valScript, _ := smartcontract.CreateDefaultMultiSigRedeemScript(validators)
|
||||||
valScript, _ := smartcontract.CreateMultiSigRedeemScript(
|
|
||||||
vlen-(vlen-1)/3,
|
|
||||||
validators,
|
|
||||||
)
|
|
||||||
witness := transaction.Witness{
|
witness := transaction.Witness{
|
||||||
VerificationScript: valScript,
|
VerificationScript: valScript,
|
||||||
}
|
}
|
||||||
|
@ -393,7 +389,7 @@ func addSigners(txs ...*transaction.Transaction) {
|
||||||
|
|
||||||
func signTx(bc *Blockchain, txs ...*transaction.Transaction) error {
|
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.CreateDefaultMultiSigRedeemScript(validators)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to sign tx: %w", err)
|
return fmt.Errorf("failed to sign tx: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"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/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/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"
|
||||||
)
|
)
|
||||||
|
@ -73,7 +72,7 @@ func (g *GAS) Initialize(ic *interop.Context) error {
|
||||||
if g.nep5TokenNative.getTotalSupply(ic.DAO).Sign() != 0 {
|
if g.nep5TokenNative.getTotalSupply(ic.DAO).Sign() != 0 {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
}
|
}
|
||||||
h, _, err := getStandbyValidatorsHash(ic)
|
h, err := getStandbyValidatorsHash(ic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -103,13 +102,12 @@ func (g *GAS) OnPersist(ic *interop.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStandbyValidatorsHash(ic *interop.Context) (util.Uint160, []*keys.PublicKey, error) {
|
func getStandbyValidatorsHash(ic *interop.Context) (util.Uint160, error) {
|
||||||
vs := ic.Chain.GetStandByValidators()
|
s, err := smartcontract.CreateDefaultMultiSigRedeemScript(ic.Chain.GetStandByValidators())
|
||||||
s, err := smartcontract.CreateMultiSigRedeemScript(len(vs)/2+1, vs)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.Uint160{}, nil, err
|
return util.Uint160{}, err
|
||||||
}
|
}
|
||||||
return hash.Hash160(s), vs, nil
|
return hash.Hash160(s), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func chainOnPersist(fs ...func(*interop.Context) error) func(*interop.Context) error {
|
func chainOnPersist(fs ...func(*interop.Context) error) func(*interop.Context) error {
|
||||||
|
|
|
@ -136,23 +136,17 @@ func (n *NEO) Initialize(ic *interop.Context) error {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
h, vs, err := getStandbyValidatorsHash(ic)
|
h, err := getStandbyValidatorsHash(ic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
n.mint(ic, h, big.NewInt(NEOTotalSupply))
|
n.mint(ic, h, big.NewInt(NEOTotalSupply))
|
||||||
|
|
||||||
err = ic.DAO.PutStorageItem(n.ContractID, []byte{prefixVotersCount}, &state.StorageItem{Value: []byte{0}})
|
err = ic.DAO.PutStorageItem(n.ContractID, []byte{prefixVotersCount}, &state.StorageItem{Value: []byte{}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range vs {
|
|
||||||
if err := n.RegisterCandidateInternal(ic, vs[i]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,6 +416,7 @@ func (n *NEO) GetValidatorsInternal(bc blockchainer.Blockchainer, d dao.DAO) (ke
|
||||||
count = len(result)
|
count = len(result)
|
||||||
}
|
}
|
||||||
result = result[:count]
|
result = result[:count]
|
||||||
|
sort.Sort(result)
|
||||||
n.validators.Store(result)
|
n.validators.Store(result)
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
|
@ -31,9 +32,11 @@ func TestNEO_Vote(t *testing.T) {
|
||||||
ic := bc.newInteropContext(trigger.System, bc.dao, nil, tx)
|
ic := bc.newInteropContext(trigger.System, bc.dao, nil, tx)
|
||||||
ic.VM = vm.New()
|
ic.VM = vm.New()
|
||||||
|
|
||||||
|
standBySorted := bc.GetStandByValidators()
|
||||||
|
sort.Sort(standBySorted)
|
||||||
pubs, err := neo.GetValidatorsInternal(bc, ic.DAO)
|
pubs, err := neo.GetValidatorsInternal(bc, ic.DAO)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, bc.GetStandByValidators(), pubs)
|
require.Equal(t, standBySorted, pubs)
|
||||||
|
|
||||||
sz := testchain.Size()
|
sz := testchain.Size()
|
||||||
|
|
||||||
|
@ -62,21 +65,10 @@ func TestNEO_Vote(t *testing.T) {
|
||||||
require.NoError(t, neo.VoteInternal(ic, h, candidates[i]))
|
require.NoError(t, neo.VoteInternal(ic, h, candidates[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
// First 3 validators must be the ones we have voted for.
|
// We still haven't voted enough validators in.
|
||||||
pubs, err = neo.GetValidatorsInternal(bc, ic.DAO)
|
pubs, err = neo.GetValidatorsInternal(bc, ic.DAO)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
for i := 1; i < sz; i++ {
|
require.Equal(t, standBySorted, pubs)
|
||||||
require.Equal(t, pubs[i-1], candidates[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
var ok bool
|
|
||||||
for _, p := range bc.GetStandByValidators() {
|
|
||||||
if pubs[sz-1].Equal(p) {
|
|
||||||
ok = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
require.True(t, ok, "last validator must be stand by")
|
|
||||||
|
|
||||||
// Register and give some value to the last validator.
|
// Register and give some value to the last validator.
|
||||||
require.NoError(t, neo.RegisterCandidateInternal(ic, candidates[0]))
|
require.NoError(t, neo.RegisterCandidateInternal(ic, candidates[0]))
|
||||||
|
@ -88,7 +80,9 @@ func TestNEO_Vote(t *testing.T) {
|
||||||
|
|
||||||
pubs, err = neo.GetValidatorsInternal(bc, ic.DAO)
|
pubs, err = neo.GetValidatorsInternal(bc, ic.DAO)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, candidates, pubs)
|
sortedCandidates := candidates.Copy()
|
||||||
|
sort.Sort(sortedCandidates)
|
||||||
|
require.EqualValues(t, sortedCandidates, pubs)
|
||||||
|
|
||||||
require.NoError(t, neo.UnregisterCandidateInternal(ic, candidates[0]))
|
require.NoError(t, neo.UnregisterCandidateInternal(ic, candidates[0]))
|
||||||
require.Error(t, neo.VoteInternal(ic, h, candidates[0]))
|
require.Error(t, neo.VoteInternal(ic, h, candidates[0]))
|
||||||
|
|
|
@ -118,11 +118,7 @@ func committeeFromConfig(cfg config.ProtocolConfiguration) ([]*keys.PublicKey, e
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNextConsensusAddress(validators []*keys.PublicKey) (val util.Uint160, err error) {
|
func getNextConsensusAddress(validators []*keys.PublicKey) (val util.Uint160, err error) {
|
||||||
vlen := len(validators)
|
raw, err := smartcontract.CreateDefaultMultiSigRedeemScript(validators)
|
||||||
raw, err := smartcontract.CreateMultiSigRedeemScript(
|
|
||||||
vlen-(vlen-1)/3,
|
|
||||||
validators,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return val, err
|
return val, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ func MultisigVerificationScript() []byte {
|
||||||
pubs = append(pubs, priv.PublicKey())
|
pubs = append(pubs, priv.PublicKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
script, err := smartcontract.CreateMultiSigRedeemScript(3, pubs)
|
script, err := smartcontract.CreateDefaultMultiSigRedeemScript(pubs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func (bq *blockQueue) run() {
|
||||||
err := bq.chain.AddBlock(minblock)
|
err := bq.chain.AddBlock(minblock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// The block might already be added by consensus.
|
// The block might already be added by consensus.
|
||||||
if _, errget := bq.chain.GetBlock(minblock.Hash()); errget != nil {
|
if bq.chain.BlockHeight() < minblock.Index {
|
||||||
bq.log.Warn("blockQueue: failed adding block into the blockchain",
|
bq.log.Warn("blockQueue: failed adding block into the blockchain",
|
||||||
zap.String("error", err.Error()),
|
zap.String("error", err.Error()),
|
||||||
zap.Uint32("blockHeight", bq.chain.BlockHeight()),
|
zap.Uint32("blockHeight", bq.chain.BlockHeight()),
|
||||||
|
|
|
@ -856,7 +856,7 @@ func (s *Server) getValidators(_ request.Params) (interface{}, *response.Error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, response.NewRPCError("can't get enrollments", "", err)
|
return nil, response.NewRPCError("can't get enrollments", "", err)
|
||||||
}
|
}
|
||||||
var res []result.Validator
|
var res = make([]result.Validator, 0)
|
||||||
for _, v := range enrollments {
|
for _, v := range enrollments {
|
||||||
res = append(res, result.Validator{
|
res = append(res, result.Validator{
|
||||||
PublicKey: *v.Key,
|
PublicKey: *v.Key,
|
||||||
|
|
|
@ -52,8 +52,8 @@ type rpcTestCase struct {
|
||||||
check func(t *testing.T, e *executor, result interface{})
|
check func(t *testing.T, e *executor, result interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
const testContractHash = "36c3b0c85d98607db00b711885ec3e411d9b1672"
|
const testContractHash = "5b5f77b947194ba45ff5fa1ba6e066af5636d110"
|
||||||
const deploymentTxHash = "60a1fc8ceb7948d9933aec0cedd148441568575c40af7e0985cc366ed153d57e"
|
const deploymentTxHash = "af0f94f6bdc5aada7abf1db19f1fcd2ea56cea596c41dc4abdfa6cd9664a7d72"
|
||||||
|
|
||||||
var rpcTestCases = map[string][]rpcTestCase{
|
var rpcTestCases = map[string][]rpcTestCase{
|
||||||
"getapplicationlog": {
|
"getapplicationlog": {
|
||||||
|
@ -451,6 +451,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
||||||
result: func(*executor) interface{} {
|
result: func(*executor) interface{} {
|
||||||
return &[]result.Validator{}
|
return &[]result.Validator{}
|
||||||
},
|
},
|
||||||
|
/* preview3 doesn't return any validators until there is a vote
|
||||||
check: func(t *testing.T, e *executor, validators interface{}) {
|
check: func(t *testing.T, e *executor, validators interface{}) {
|
||||||
var expected []result.Validator
|
var expected []result.Validator
|
||||||
sBValidators := e.chain.GetStandByValidators()
|
sBValidators := e.chain.GetStandByValidators()
|
||||||
|
@ -467,6 +468,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
||||||
|
|
||||||
assert.ElementsMatch(t, expected, *actual)
|
assert.ElementsMatch(t, expected, *actual)
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"getversion": {
|
"getversion": {
|
||||||
|
@ -1025,7 +1027,7 @@ func checkNep5Balances(t *testing.T, e *executor, acc interface{}) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Asset: e.chain.UtilityTokenHash(),
|
Asset: e.chain.UtilityTokenHash(),
|
||||||
Amount: "915.78962700",
|
Amount: "915.61054740",
|
||||||
LastUpdated: 6,
|
LastUpdated: 6,
|
||||||
}},
|
}},
|
||||||
Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(),
|
Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(),
|
||||||
|
@ -1143,16 +1145,6 @@ func checkNep5TransfersAux(t *testing.T, e *executor, acc interface{}, start, en
|
||||||
}
|
}
|
||||||
netFee += b.Transactions[j].NetworkFee
|
netFee += b.Transactions[j].NetworkFee
|
||||||
}
|
}
|
||||||
if i > 0 {
|
|
||||||
expected.Received = append(expected.Received, result.NEP5Transfer{
|
|
||||||
Timestamp: b.Timestamp,
|
|
||||||
Asset: e.chain.UtilityTokenHash(),
|
|
||||||
Address: "", // minted from network fees.
|
|
||||||
Amount: amountToString(big.NewInt(netFee), 8),
|
|
||||||
Index: b.Index,
|
|
||||||
TxHash: b.Hash(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
require.Equal(t, expected.Address, res.Address)
|
require.Equal(t, expected.Address, res.Address)
|
||||||
|
|
||||||
|
|
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
Binary file not shown.
|
@ -10,7 +10,8 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateMultiSigRedeemScript creates a script runnable by the VM.
|
// CreateMultiSigRedeemScript creates an "m out of n" type verification script
|
||||||
|
// where n is the length of publicKeys.
|
||||||
func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, error) {
|
func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, error) {
|
||||||
if m < 1 {
|
if m < 1 {
|
||||||
return nil, fmt.Errorf("param m cannot be smaller or equal to 1 got %d", m)
|
return nil, fmt.Errorf("param m cannot be smaller or equal to 1 got %d", m)
|
||||||
|
@ -34,3 +35,11 @@ func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, erro
|
||||||
|
|
||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateDefaultMultiSigRedeemScript creates an "m out of n" type verification script
|
||||||
|
// using publicKeys length with the default BFT assumptions of (n - (n-1)/3) for m.
|
||||||
|
func CreateDefaultMultiSigRedeemScript(publicKeys keys.PublicKeys) ([]byte, error) {
|
||||||
|
n := len(publicKeys)
|
||||||
|
m := n - (n-1)/3
|
||||||
|
return CreateMultiSigRedeemScript(m, publicKeys)
|
||||||
|
}
|
||||||
|
|
|
@ -36,3 +36,50 @@ func TestCreateMultiSigRedeemScript(t *testing.T) {
|
||||||
assert.Equal(t, opcode.SYSCALL, opcode.Opcode(br.ReadB()))
|
assert.Equal(t, opcode.SYSCALL, opcode.Opcode(br.ReadB()))
|
||||||
assert.Equal(t, emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")), br.ReadU32LE())
|
assert.Equal(t, emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")), br.ReadU32LE())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateDefaultMultiSigRedeemScript(t *testing.T) {
|
||||||
|
var validators = make([]*keys.PublicKey, 0)
|
||||||
|
|
||||||
|
var addKey = func() {
|
||||||
|
key, err := keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
validators = append(validators, key.PublicKey())
|
||||||
|
}
|
||||||
|
var checkM = func(m int) {
|
||||||
|
validScript, err := CreateMultiSigRedeemScript(m, validators)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defaultScript, err := CreateDefaultMultiSigRedeemScript(validators)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, validScript, defaultScript)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1 out of 1
|
||||||
|
addKey()
|
||||||
|
checkM(1)
|
||||||
|
|
||||||
|
// 2 out of 2
|
||||||
|
addKey()
|
||||||
|
checkM(2)
|
||||||
|
|
||||||
|
// 3 out of 4
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
addKey()
|
||||||
|
}
|
||||||
|
checkM(3)
|
||||||
|
|
||||||
|
// 5 out of 6
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
addKey()
|
||||||
|
}
|
||||||
|
checkM(5)
|
||||||
|
|
||||||
|
// 5 out of 7
|
||||||
|
addKey()
|
||||||
|
checkM(5)
|
||||||
|
|
||||||
|
// 7 out of 10
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
addKey()
|
||||||
|
}
|
||||||
|
checkM(7)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue