core: drop GetScriptHashesForVerifying

It no longer depends on blockchain state and there can't ever be an error, in
fact we can always iterate over signers, so copying these hashes doesn't make
much sense at all as well as sorting arrays in verifyTxWitnesses (witnesses
order must match signers order).
This commit is contained in:
Roman Khimov 2020-08-06 21:16:34 +03:00
parent c19838ea67
commit 791c983304
4 changed files with 11 additions and 44 deletions

View file

@ -1206,20 +1206,16 @@ func (bc *Blockchain) verifyTx(t *transaction.Transaction, block *block.Block) e
if t.ValidUntilBlock <= height || t.ValidUntilBlock > height+transaction.MaxValidUntilBlockIncrement { if t.ValidUntilBlock <= height || t.ValidUntilBlock > height+transaction.MaxValidUntilBlockIncrement {
return fmt.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)
if err != nil {
return err
}
blockedAccounts, err := bc.contracts.Policy.GetBlockedAccountsInternal(bc.dao) blockedAccounts, err := bc.contracts.Policy.GetBlockedAccountsInternal(bc.dao)
if err != nil { if err != nil {
return err return err
} }
for _, h := range hashes { for _, signer := range t.Signers {
i := sort.Search(len(blockedAccounts), func(i int) bool { i := sort.Search(len(blockedAccounts), func(i int) bool {
return !blockedAccounts[i].Less(h) return !blockedAccounts[i].Less(signer.Account)
}) })
if i != len(blockedAccounts) && blockedAccounts[i].Equals(h) { if i != len(blockedAccounts) && blockedAccounts[i].Equals(signer.Account) {
return fmt.Errorf("policy check failed: account %s is blocked", h.StringLE()) return fmt.Errorf("policy check failed: account %s is blocked", signer.Account.StringLE())
} }
} }
maxBlockSystemFee := bc.contracts.Policy.GetMaxBlockSystemFeeInternal(bc.dao) maxBlockSystemFee := bc.contracts.Policy.GetMaxBlockSystemFeeInternal(bc.dao)
@ -1410,19 +1406,6 @@ func (bc *Blockchain) GetEnrollments() ([]state.Validator, error) {
return bc.contracts.NEO.GetRegisteredValidators(bc.dao) return bc.contracts.NEO.GetRegisteredValidators(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)
@ -1503,20 +1486,12 @@ 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 fmt.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 {
return fmt.Errorf("witness #%d: %w", i, err) return fmt.Errorf("witness #%d: %w", i, err)
} }

View file

@ -43,7 +43,6 @@ type Blockchainer interface {
GetNEP5Balances(util.Uint160) *state.NEP5Balances GetNEP5Balances(util.Uint160) *state.NEP5Balances
GetValidators() ([]*keys.PublicKey, error) GetValidators() ([]*keys.PublicKey, error)
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)

View file

@ -516,14 +516,10 @@ func (p *Policy) CheckPolicy(ic *interop.Context, tx *transaction.Transaction) e
if err != nil { if err != nil {
return fmt.Errorf("unable to get blocked accounts list: %w", err) return fmt.Errorf("unable to get blocked accounts list: %w", err)
} }
scriptHashes, err := ic.Chain.GetScriptHashesForVerifying(tx)
if err != nil {
return fmt.Errorf("unable to get tx script hashes: %w", err)
}
for _, acc := range ba { for _, acc := range ba {
for _, hash := range scriptHashes { for _, signer := range tx.Signers {
if acc.Equals(hash) { if acc.Equals(signer.Account) {
return fmt.Errorf("account %s is blocked", hash.StringLE()) return fmt.Errorf("account %s is blocked", acc.StringLE())
} }
} }
} }

View file

@ -109,9 +109,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")
} }