forked from TrueCloudLab/neoneo-go
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:
parent
c19838ea67
commit
791c983304
4 changed files with 11 additions and 44 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue