testchain: support signing tx by committee

This commit is contained in:
Evgeniy Stratonikov 2021-01-21 12:23:53 +03:00
parent fbbcb16fa1
commit 24d9a31476
3 changed files with 43 additions and 15 deletions

View file

@ -91,17 +91,27 @@ func NewDeployTx(bc blockchainer.Blockchainer, name string, sender util.Uint160,
// SignTx signs provided transactions with validator keys. // SignTx signs provided transactions with validator keys.
func SignTx(bc blockchainer.Blockchainer, txs ...*transaction.Transaction) error { func SignTx(bc blockchainer.Blockchainer, txs ...*transaction.Transaction) error {
signTxGeneric(bc, Sign, ownerScript, txs...)
return nil
}
// SignTxCommittee signs transactions by committee.
func SignTxCommittee(bc blockchainer.Blockchainer, txs ...*transaction.Transaction) error {
signTxGeneric(bc, SignCommittee, CommitteeVerificationScript(), txs...)
return nil
}
func signTxGeneric(bc blockchainer.Blockchainer, sign func([]byte) []byte, verif []byte, txs ...*transaction.Transaction) {
for _, tx := range txs { for _, tx := range txs {
size := io.GetVarSize(tx) size := io.GetVarSize(tx)
netFee, sizeDelta := fee.Calculate(bc.GetPolicer().GetBaseExecFee(), ownerScript) netFee, sizeDelta := fee.Calculate(bc.GetPolicer().GetBaseExecFee(), verif)
tx.NetworkFee += netFee tx.NetworkFee += netFee
size += sizeDelta size += sizeDelta
tx.NetworkFee += int64(size) * bc.FeePerByte() tx.NetworkFee += int64(size) * bc.FeePerByte()
data := tx.GetSignedPart() data := tx.GetSignedPart()
tx.Scripts = []transaction.Witness{{ tx.Scripts = []transaction.Witness{{
InvocationScript: Sign(data), InvocationScript: sign(data),
VerificationScript: ownerScript, VerificationScript: verif,
}} }}
} }
return nil
} }

View file

@ -139,7 +139,7 @@ func TestAddBlockStateRoot(t *testing.T) {
tx := newNEP17Transfer(bc.contracts.NEO.Hash, neoOwner, util.Uint160{}, 1) tx := newNEP17Transfer(bc.contracts.NEO.Hash, neoOwner, util.Uint160{}, 1)
tx.ValidUntilBlock = bc.BlockHeight() + 1 tx.ValidUntilBlock = bc.BlockHeight() + 1
addSigners(tx) addSigners(neoOwner, tx)
require.NoError(t, testchain.SignTx(bc, tx)) require.NoError(t, testchain.SignTx(bc, tx))
lastBlock := bc.topBlock.Load().(*block.Block) lastBlock := bc.topBlock.Load().(*block.Block)
@ -198,7 +198,7 @@ func TestGetHeader(t *testing.T) {
bc := newTestChain(t) bc := newTestChain(t)
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0) tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
tx.ValidUntilBlock = bc.BlockHeight() + 1 tx.ValidUntilBlock = bc.BlockHeight() + 1
addSigners(tx) addSigners(neoOwner, tx)
assert.Nil(t, testchain.SignTx(bc, tx)) assert.Nil(t, testchain.SignTx(bc, tx))
block := bc.newBlock(tx) block := bc.newBlock(tx)
err := bc.AddBlock(block) err := bc.AddBlock(block)
@ -1176,7 +1176,7 @@ func TestIsTxStillRelevant(t *testing.T) {
txDeploy, h, err := testchain.NewDeployTx(bc, "TestVerify", neoOwner, strings.NewReader(src)) txDeploy, h, err := testchain.NewDeployTx(bc, "TestVerify", neoOwner, strings.NewReader(src))
require.NoError(t, err) require.NoError(t, err)
txDeploy.ValidUntilBlock = bc.BlockHeight() + 1 txDeploy.ValidUntilBlock = bc.BlockHeight() + 1
addSigners(txDeploy) addSigners(neoOwner, txDeploy)
require.NoError(t, testchain.SignTx(bc, txDeploy)) require.NoError(t, testchain.SignTx(bc, txDeploy))
require.NoError(t, bc.AddBlock(bc.newBlock(txDeploy))) require.NoError(t, bc.AddBlock(bc.newBlock(txDeploy)))

View file

@ -400,10 +400,10 @@ func newDeployTx(t *testing.T, bc *Blockchain, sender util.Uint160, name, ctrNam
return tx, h return tx, h
} }
func addSigners(txs ...*transaction.Transaction) { func addSigners(sender util.Uint160, txs ...*transaction.Transaction) {
for _, tx := range txs { for _, tx := range txs {
tx.Signers = []transaction.Signer{{ tx.Signers = []transaction.Signer{{
Account: neoOwner, Account: sender,
Scopes: transaction.CalledByEntry, Scopes: transaction.CalledByEntry,
AllowedContracts: nil, AllowedContracts: nil,
AllowedGroups: nil, AllowedGroups: nil,
@ -428,8 +428,8 @@ func addNetworkFee(bc *Blockchain, tx *transaction.Transaction, sender *wallet.A
return nil return nil
} }
func prepareContractMethodInvoke(chain *Blockchain, sysfee int64, func prepareContractMethodInvokeGeneric(chain *Blockchain, sysfee int64,
hash util.Uint160, method string, args ...interface{}) (*transaction.Transaction, error) { hash util.Uint160, method string, isCommittee bool, args ...interface{}) (*transaction.Transaction, error) {
w := io.NewBufBinWriter() w := io.NewBufBinWriter()
emit.AppCall(w.BinWriter, hash, method, callflag.All, args...) emit.AppCall(w.BinWriter, hash, method, callflag.All, args...)
if w.Err != nil { if w.Err != nil {
@ -438,14 +438,26 @@ func prepareContractMethodInvoke(chain *Blockchain, sysfee int64,
script := w.Bytes() script := w.Bytes()
tx := transaction.New(chain.GetConfig().Magic, script, sysfee) tx := transaction.New(chain.GetConfig().Magic, script, sysfee)
tx.ValidUntilBlock = chain.blockHeight + 1 tx.ValidUntilBlock = chain.blockHeight + 1
addSigners(tx) var err error
err := testchain.SignTx(chain, tx) if isCommittee {
addSigners(testchain.CommitteeScriptHash(), tx)
err = testchain.SignTxCommittee(chain, tx)
} else {
addSigners(neoOwner, tx)
err = testchain.SignTx(chain, tx)
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
return tx, nil return tx, nil
} }
func prepareContractMethodInvoke(chain *Blockchain, sysfee int64,
hash util.Uint160, method string, args ...interface{}) (*transaction.Transaction, error) {
return prepareContractMethodInvokeGeneric(chain, sysfee, hash,
method, false, args...)
}
func persistBlock(chain *Blockchain, txs ...*transaction.Transaction) ([]*state.AppExecResult, error) { func persistBlock(chain *Blockchain, txs ...*transaction.Transaction) ([]*state.AppExecResult, error) {
b := chain.newBlock(txs...) b := chain.newBlock(txs...)
err := chain.AddBlock(b) err := chain.AddBlock(b)
@ -465,7 +477,13 @@ func persistBlock(chain *Blockchain, txs ...*transaction.Transaction) ([]*state.
} }
func invokeContractMethod(chain *Blockchain, sysfee int64, hash util.Uint160, method string, args ...interface{}) (*state.AppExecResult, error) { func invokeContractMethod(chain *Blockchain, sysfee int64, hash util.Uint160, method string, args ...interface{}) (*state.AppExecResult, error) {
tx, err := prepareContractMethodInvoke(chain, sysfee, hash, method, args...) return invokeContractMethodGeneric(chain, sysfee, hash, method, false, args...)
}
func invokeContractMethodGeneric(chain *Blockchain, sysfee int64, hash util.Uint160, method string,
isCommittee bool, args ...interface{}) (*state.AppExecResult, error) {
tx, err := prepareContractMethodInvokeGeneric(chain, sysfee, hash,
method, isCommittee, args...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -512,7 +530,7 @@ func transferTokenFromMultisigAccount(t *testing.T, chain *Blockchain, to, token
transferTx := newNEP17Transfer(tokenHash, testchain.MultisigScriptHash(), to, amount, additionalArgs...) transferTx := newNEP17Transfer(tokenHash, testchain.MultisigScriptHash(), to, amount, additionalArgs...)
transferTx.SystemFee = 100000000 transferTx.SystemFee = 100000000
transferTx.ValidUntilBlock = chain.BlockHeight() + 1 transferTx.ValidUntilBlock = chain.BlockHeight() + 1
addSigners(transferTx) addSigners(neoOwner, transferTx)
require.NoError(t, testchain.SignTx(chain, transferTx)) require.NoError(t, testchain.SignTx(chain, transferTx))
b := chain.newBlock(transferTx) b := chain.newBlock(transferTx)
require.NoError(t, chain.AddBlock(b)) require.NoError(t, chain.AddBlock(b))