Merge pull request #1303 from nspcc-dev/some-cleanup

Cleanup some old code
This commit is contained in:
Roman Khimov 2020-08-12 16:21:37 +03:00 committed by GitHub
commit 483eed1852
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 39 additions and 564 deletions

View file

@ -1,20 +0,0 @@
# Integration package
The main goal is to have integration tests here.
### Performance test
Right now we have `performance_test.go` to measure number of processed TX per second.
In order to run it:
```
$ cd integration
$ go test -bench=. -benchmem
```
Result:
```
10000 402421 ns/op 177370 B/op 90 allocs/op
PASS
ok github.com/nspcc-dev/neo-go/integration 4.360s
```
Which means that in 4.360 seconds neo-go processes 10 000 transactions.

View file

@ -1,110 +0,0 @@
package integration
import (
"math/rand"
"testing"
"github.com/nspcc-dev/neo-go/pkg/config"
"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/storage"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"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/network"
"github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
)
// Benchmark test to measure number of processed TX.
// Same benchmark made on reference C# node https://github.com/neo-project/neo/issues/1321.
func BenchmarkTXPerformanceTest(t *testing.B) {
net := netmode.UnitTestNet
configPath := "../config"
cfg, err := config.Load(configPath, net)
require.NoError(t, err, "could not load config")
logger := zaptest.NewLogger(t)
memoryStore := storage.NewMemoryStore()
chain, err := core.NewBlockchain(memoryStore, cfg.ProtocolConfiguration, logger)
require.NoError(t, err, "could not create chain")
go chain.Run()
serverConfig := network.NewServerConfig(cfg)
server, err := network.NewServer(serverConfig, chain, logger)
require.NoError(t, err, "could not create server")
data := prepareData(t)
t.ResetTimer()
for n := 0; n < t.N; n++ {
assert.Equal(t, network.RelaySucceed, server.RelayTxn(data[n]))
assert.Equal(t, network.RelayAlreadyExists, server.RelayTxn(data[n]))
}
chain.Close()
}
func prepareData(t *testing.B) []*transaction.Transaction {
var data []*transaction.Transaction
wif := getWif(t)
acc, err := wallet.NewAccountFromWIF(wif.S)
require.NoError(t, err)
for n := 0; n < t.N; n++ {
tx := getTX(t, wif)
require.NoError(t, acc.SignTx(tx))
data = append(data, tx)
}
return data
}
// getWif returns Wif.
func getWif(t *testing.B) *keys.WIF {
var (
wifEncoded = "KxhEDBQyyEFymvfJD96q8stMbJMbZUb6D1PmXqBWZDU2WvbvVs9o"
version = byte(0x00)
)
wif, err := keys.WIFDecode(wifEncoded, version)
require.NoError(t, err)
return wif
}
// getTX returns Invocation transaction with some random attributes in order to have different hashes.
func getTX(t *testing.B, wif *keys.WIF) *transaction.Transaction {
fromAddress := wif.PrivateKey.Address()
fromAddressHash, err := address.StringToUint160(fromAddress)
require.NoError(t, err)
tx := transaction.New(netmode.UnitTestNet, []byte{0x51}, 1)
tx.Version = 0
tx.Signers = []transaction.Signer{
{
Account: fromAddressHash,
Scopes: transaction.FeeOnly,
},
}
tx.Attributes = append(tx.Attributes,
transaction.Attribute{
Usage: transaction.DescriptionURL,
Data: []byte(randString(10)),
})
return tx
}
// String returns a random string with the n as its length.
func randString(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = byte(Int(65, 90))
}
return string(b)
}
// Int returns a random integer in [min,max).
func Int(min, max int) int {
return min + rand.Intn(max-min)
}

View file

@ -1,6 +0,0 @@
// Package integration contains integration tests.
// See README.md for more info.
// This file exists with the sole purpose to get rid of
// "go build github.com/nspcc-dev/neo-go/integration: no non-test Go files in *"
// when running `go test -coverpkg=all`.
package integration

View file

@ -1034,15 +1034,6 @@ func (bc *Blockchain) GetContractScriptHash(id int32) (util.Uint160, error) {
return bc.dao.GetContractScriptHash(id)
}
// GetAccountState returns the account state from its script hash.
func (bc *Blockchain) GetAccountState(scriptHash util.Uint160) *state.Account {
as, err := bc.dao.GetAccountState(scriptHash)
if as == nil && err != storage.ErrKeyNotFound {
bc.log.Warn("failed to get account state", zap.Error(err))
}
return as
}
// GetConfig returns the config stored in the blockchain.
func (bc *Blockchain) GetConfig() config.ProtocolConfiguration {
return bc.config
@ -1520,10 +1511,6 @@ func hashAndIndexToBytes(h util.Uint256, index uint32) []byte {
return buf.Bytes()
}
func (bc *Blockchain) secondsPerBlock() int {
return bc.config.SecondsPerBlock
}
func (bc *Blockchain) newInteropContext(trigger trigger.Type, d dao.DAO, block *block.Block, tx *transaction.Transaction) *interop.Context {
ic := interop.NewContext(trigger, bc, d, bc.contracts.Contracts, block, tx, bc.log)
ic.Functions = [][]interop.Function{systemInterops, neoInterops}

View file

@ -37,7 +37,6 @@ type Blockchainer interface {
CurrentBlockHash() util.Uint256
HasBlock(util.Uint256) bool
HasTransaction(util.Uint256) bool
GetAccountState(util.Uint160) *state.Account
GetAppExecResult(util.Uint256) (*state.AppExecResult, error)
GetNextBlockValidators() ([]*keys.PublicKey, error)
GetNEP5Balances(util.Uint160) *state.NEP5Balances

View file

@ -13,7 +13,6 @@ import (
// objects in the storeBlock().
type Cached struct {
DAO
accounts map[util.Uint160]*state.Account
contracts map[util.Uint160]*state.Contract
balances map[util.Uint160]*state.NEP5Balances
transfers map[util.Uint160]map[uint32]*state.NEP5TransferLog
@ -23,34 +22,10 @@ type Cached struct {
// NewCached returns new Cached wrapping around given backing store.
func NewCached(d DAO) *Cached {
accs := make(map[util.Uint160]*state.Account)
ctrs := make(map[util.Uint160]*state.Contract)
balances := make(map[util.Uint160]*state.NEP5Balances)
transfers := make(map[util.Uint160]map[uint32]*state.NEP5TransferLog)
return &Cached{d.GetWrapped(), accs, ctrs, balances, transfers, false}
}
// GetAccountStateOrNew retrieves Account from cache or underlying store
// or creates a new one if it doesn't exist.
func (cd *Cached) GetAccountStateOrNew(hash util.Uint160) (*state.Account, error) {
if cd.accounts[hash] != nil {
return cd.accounts[hash], nil
}
return cd.DAO.GetAccountStateOrNew(hash)
}
// GetAccountState retrieves Account from cache or underlying store.
func (cd *Cached) GetAccountState(hash util.Uint160) (*state.Account, error) {
if cd.accounts[hash] != nil {
return cd.accounts[hash], nil
}
return cd.DAO.GetAccountState(hash)
}
// PutAccountState saves given Account in the cache.
func (cd *Cached) PutAccountState(as *state.Account) error {
cd.accounts[as.ScriptHash] = as
return nil
return &Cached{d.GetWrapped(), ctrs, balances, transfers, false}
}
// GetContractState returns contract state from cache or underlying store.
@ -149,13 +124,6 @@ func (cd *Cached) Persist() (int, error) {
}
buf := io.NewBufBinWriter()
for sc := range cd.accounts {
err := cd.DAO.putAccountState(cd.accounts[sc], buf)
if err != nil {
return 0, err
}
buf.Reset()
}
for acc, bs := range cd.balances {
err := cd.DAO.putNEP5Balances(acc, bs, buf)
if err != nil {
@ -177,7 +145,6 @@ func (cd *Cached) Persist() (int, error) {
// GetWrapped implements DAO interface.
func (cd *Cached) GetWrapped() DAO {
return &Cached{cd.DAO.GetWrapped(),
cd.accounts,
cd.contracts,
cd.balances,
cd.transfers,

View file

@ -13,43 +13,6 @@ import (
"github.com/stretchr/testify/require"
)
func TestCachedDaoAccounts(t *testing.T) {
store := storage.NewMemoryStore()
// Persistent DAO to check for backing storage.
pdao := NewSimple(store, netmode.UnitTestNet)
// Cached DAO.
cdao := NewCached(pdao)
hash := random.Uint160()
_, err := cdao.GetAccountState(hash)
require.NotNil(t, err)
acc, err := cdao.GetAccountStateOrNew(hash)
require.Nil(t, err)
_, err = pdao.GetAccountState(hash)
require.NotNil(t, err)
acc.Version = 42
require.NoError(t, cdao.PutAccountState(acc))
_, err = pdao.GetAccountState(hash)
require.NotNil(t, err)
acc2, err := cdao.GetAccountState(hash)
require.Nil(t, err)
require.Equal(t, acc, acc2)
acc2, err = cdao.GetAccountStateOrNew(hash)
require.Nil(t, err)
require.Equal(t, acc, acc2)
_, err = cdao.Persist()
require.Nil(t, err)
acct, err := pdao.GetAccountState(hash)
require.Nil(t, err)
require.Equal(t, acc, acct)
}
func TestCachedDaoContracts(t *testing.T) {
store := storage.NewMemoryStore()
pdao := NewSimple(store, netmode.UnitTestNet)

View file

@ -21,8 +21,6 @@ type DAO interface {
AppendNEP5Transfer(acc util.Uint160, index uint32, tr *state.NEP5Transfer) (bool, error)
DeleteContractState(hash util.Uint160) error
DeleteStorageItem(id int32, key []byte) error
GetAccountState(hash util.Uint160) (*state.Account, error)
GetAccountStateOrNew(hash util.Uint160) (*state.Account, error)
GetAndDecode(entity io.Serializable, key []byte) error
GetAppExecResult(hash util.Uint256) (*state.AppExecResult, error)
GetBatch() *storage.MemBatch
@ -46,7 +44,6 @@ type DAO interface {
GetWrapped() DAO
HasTransaction(hash util.Uint256) bool
Persist() (int, error)
PutAccountState(as *state.Account) error
PutAppExecResult(aer *state.AppExecResult) error
PutContractState(cs *state.Contract) error
PutCurrentHeader(hashAndIndex []byte) error
@ -57,7 +54,6 @@ type DAO interface {
StoreAsBlock(block *block.Block) error
StoreAsCurrentBlock(block *block.Block) error
StoreAsTransaction(tx *transaction.Transaction, index uint32) error
putAccountState(as *state.Account, buf *io.BufBinWriter) error
putNEP5Balances(acc util.Uint160, bs *state.NEP5Balances, buf *io.BufBinWriter) error
}
@ -112,45 +108,6 @@ func (dao *Simple) putWithBuffer(entity io.Serializable, key []byte, buf *io.Buf
return dao.Store.Put(key, buf.Bytes())
}
// -- start accounts.
// GetAccountStateOrNew retrieves Account from temporary or persistent Store
// or creates a new one if it doesn't exist and persists it.
func (dao *Simple) GetAccountStateOrNew(hash util.Uint160) (*state.Account, error) {
account, err := dao.GetAccountState(hash)
if err != nil {
if err != storage.ErrKeyNotFound {
return nil, err
}
account = state.NewAccount(hash)
}
return account, nil
}
// GetAccountState returns Account from the given Store if it's
// present there. Returns nil otherwise.
func (dao *Simple) GetAccountState(hash util.Uint160) (*state.Account, error) {
account := &state.Account{}
key := storage.AppendPrefix(storage.STAccount, hash.BytesBE())
err := dao.GetAndDecode(account, key)
if err != nil {
return nil, err
}
return account, err
}
// PutAccountState saves given Account in given store.
func (dao *Simple) PutAccountState(as *state.Account) error {
return dao.putAccountState(as, io.NewBufBinWriter())
}
func (dao *Simple) putAccountState(as *state.Account, buf *io.BufBinWriter) error {
key := storage.AppendPrefix(storage.STAccount, as.ScriptHash.BytesBE())
return dao.putWithBuffer(as, key, buf)
}
// -- end accounts.
// -- start contracts.
// GetContractState returns contract state as recorded in the given

View file

@ -41,25 +41,6 @@ func (t *TestSerializable) DecodeBinary(reader *io.BinReader) {
t.field = reader.ReadString()
}
func TestGetAccountStateOrNew_New(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
hash := random.Uint160()
createdAccount, err := dao.GetAccountStateOrNew(hash)
require.NoError(t, err)
require.NotNil(t, createdAccount)
}
func TestPutAndGetAccountStateOrNew(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
hash := random.Uint160()
accountState := &state.Account{ScriptHash: hash}
err := dao.PutAccountState(accountState)
require.NoError(t, err)
gotAccount, err := dao.GetAccountStateOrNew(hash)
require.NoError(t, err)
require.Equal(t, accountState.ScriptHash, gotAccount.ScriptHash)
}
func TestPutAndGetContractState(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet)
contractState := &state.Contract{Script: []byte{}}

View file

@ -12,11 +12,6 @@ type HeaderHashList struct {
hashes []util.Uint256
}
// NewHeaderHashListFromBytes returns a new hash list from the given bytes.
func NewHeaderHashListFromBytes(b []byte) (*HeaderHashList, error) {
return nil, nil
}
// NewHeaderHashList returns a new pointer to a HeaderHashList.
func NewHeaderHashList(hashes ...util.Uint256) *HeaderHashList {
return &HeaderHashList{
@ -47,17 +42,9 @@ func (l *HeaderHashList) Last() util.Uint256 {
return l.hashes[l.Len()-1]
}
// Slice return a subslice of the underlying hashes.
// Subsliced from start to end.
// Example:
// headers := headerList.Slice(0, 2000)
func (l *HeaderHashList) Slice(start, end int) []util.Uint256 {
return l.hashes[start:end]
}
// WriteTo writes n underlying hashes to the given BinWriter
// Write writes n underlying hashes to the given BinWriter
// starting from start.
func (l *HeaderHashList) Write(bw *io.BinWriter, start, n int) error {
bw.WriteArray(l.Slice(start, start+n))
bw.WriteArray(l.hashes[start : start+n])
return bw.Err
}

View file

@ -29,8 +29,6 @@ import (
/* Missing tests:
* TestTxGetWitnesses
* TestBcGetAccount
* TestAccountGetBalance
* TestAccountIsStandard
* TestCreateContractStateFromVM
* TestContractCreate
@ -301,29 +299,10 @@ func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.C
return v, contractState, context, chain
}
func createVMAndAccState(t *testing.T) (*vm.VM, *state.Account, *interop.Context, *Blockchain) {
rawHash := "4d3b96ae1bcc5a585e075e3b81920210dec16302"
hash, err := util.Uint160DecodeStringBE(rawHash)
accountState := state.NewAccount(hash)
require.NoError(t, err)
chain := newTestChain(t)
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet), nil, nil)
v := context.SpawnVM()
return v, accountState, context, chain
}
func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interop.Context, *Blockchain) {
script := []byte{byte(opcode.PUSH1), byte(opcode.RET)}
tx := transaction.New(netmode.UnitTestNet, script, 0)
bytes := make([]byte, 1)
attributes := append(tx.Attributes, transaction.Attribute{
Usage: transaction.DescriptionURL,
Data: bytes,
})
tx.Attributes = attributes
tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3, 4}}}
chain := newTestChain(t)
context := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet), nil, tx)

View file

@ -68,28 +68,23 @@ func TestOverCapacity(t *testing.T) {
require.Equal(t, mempoolSize, mp.Count())
require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes)))
bigScript := make([]byte, 64)
bigScript[0] = byte(opcode.PUSH1)
bigScript[1] = byte(opcode.RET)
// Fees are also prioritized.
for i := 0; i < mempoolSize; i++ {
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
tx.Attributes = append(tx.Attributes, transaction.Attribute{
Usage: transaction.DescriptionURL,
Data: util.Uint256{1, 2, 3, 4}.BytesBE(),
})
tx := transaction.New(netmode.UnitTestNet, bigScript, 0)
tx.NetworkFee = 10000
tx.Nonce = txcnt
tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}}
txcnt++
// size is 84, networkFee is 10000 => feePerByte is 119
// size is ~90, networkFee is 10000 => feePerByte is 119
require.NoError(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count())
require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes)))
}
// Less prioritized txes are not allowed anymore.
tx := transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0)
tx.Attributes = append(tx.Attributes, transaction.Attribute{
Usage: transaction.DescriptionURL,
Data: util.Uint256{1, 2, 3, 4}.BytesBE(),
})
tx := transaction.New(netmode.UnitTestNet, bigScript, 0)
tx.NetworkFee = 100
tx.Nonce = txcnt
tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}}
@ -104,7 +99,7 @@ func TestOverCapacity(t *testing.T) {
tx.NetworkFee = 7000
tx.Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}}
txcnt++
// size is 51 (no attributes), networkFee is 7000 (<10000)
// size is ~51 (small script), networkFee is 7000 (<10000)
// => feePerByte is 137 (>119)
require.NoError(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count())

View file

@ -1,108 +0,0 @@
package state
import (
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/util"
)
// UnspentBalance contains input/output transactons that sum up into the
// account balance for the given asset.
type UnspentBalance struct {
Tx util.Uint256 `json:"txid"`
Index uint16 `json:"n"`
Value util.Fixed8 `json:"value"`
}
// UnspentBalances is a slice of UnspentBalance (mostly needed to sort them).
type UnspentBalances []UnspentBalance
// Account represents the state of a NEO account.
type Account struct {
Version uint8
ScriptHash util.Uint160
IsFrozen bool
Balances map[util.Uint256][]UnspentBalance
}
// NewAccount returns a new Account object.
func NewAccount(scriptHash util.Uint160) *Account {
return &Account{
Version: 0,
ScriptHash: scriptHash,
IsFrozen: false,
Balances: make(map[util.Uint256][]UnspentBalance),
}
}
// DecodeBinary decodes Account from the given BinReader.
func (s *Account) DecodeBinary(br *io.BinReader) {
s.Version = uint8(br.ReadB())
s.ScriptHash.DecodeBinary(br)
s.IsFrozen = br.ReadBool()
s.Balances = make(map[util.Uint256][]UnspentBalance)
lenBalances := br.ReadVarUint()
for i := 0; i < int(lenBalances); i++ {
key := util.Uint256{}
br.ReadBytes(key[:])
len := int(br.ReadVarUint())
ubs := make([]UnspentBalance, len)
for j := 0; j < len; j++ {
ubs[j].DecodeBinary(br)
}
s.Balances[key] = ubs
}
}
// EncodeBinary encodes Account to the given BinWriter.
func (s *Account) EncodeBinary(bw *io.BinWriter) {
bw.WriteB(byte(s.Version))
s.ScriptHash.EncodeBinary(bw)
bw.WriteBool(s.IsFrozen)
bw.WriteVarUint(uint64(len(s.Balances)))
for k, v := range s.Balances {
bw.WriteBytes(k[:])
bw.WriteVarUint(uint64(len(v)))
for i := range v {
v[i].EncodeBinary(bw)
}
}
}
// DecodeBinary implements io.Serializable interface.
func (u *UnspentBalance) DecodeBinary(r *io.BinReader) {
u.Tx.DecodeBinary(r)
u.Index = r.ReadU16LE()
u.Value.DecodeBinary(r)
}
// EncodeBinary implements io.Serializable interface.
func (u *UnspentBalance) EncodeBinary(w *io.BinWriter) {
u.Tx.EncodeBinary(w)
w.WriteU16LE(u.Index)
u.Value.EncodeBinary(w)
}
// GetBalanceValues sums all unspent outputs and returns a map of asset IDs to
// overall balances.
func (s *Account) GetBalanceValues() map[util.Uint256]util.Fixed8 {
res := make(map[util.Uint256]util.Fixed8)
for k, v := range s.Balances {
balance := util.Fixed8(0)
for _, b := range v {
balance += b.Value
}
res[k] = balance
}
return res
}
// Len returns the length of UnspentBalances (used to sort things).
func (us UnspentBalances) Len() int { return len(us) }
// Less compares two elements of UnspentBalances (used to sort things).
func (us UnspentBalances) Less(i, j int) bool { return us[i].Value < us[j].Value }
// Swap swaps two elements of UnspentBalances (used to sort things).
func (us UnspentBalances) Swap(i, j int) { us[i], us[j] = us[j], us[i] }

View file

@ -1,51 +0,0 @@
package state
import (
"testing"
"github.com/nspcc-dev/neo-go/pkg/internal/random"
"github.com/nspcc-dev/neo-go/pkg/internal/testserdes"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/stretchr/testify/assert"
)
func TestDecodeEncodeAccountState(t *testing.T) {
var (
n = 10
balances = make(map[util.Uint256][]UnspentBalance)
)
for i := 0; i < n; i++ {
asset := random.Uint256()
for j := 0; j < i+1; j++ {
balances[asset] = append(balances[asset], UnspentBalance{
Tx: random.Uint256(),
Index: uint16(random.Int(0, 65535)),
Value: util.Fixed8(int64(random.Int(1, 10000))),
})
}
}
a := &Account{
Version: 0,
ScriptHash: random.Uint160(),
IsFrozen: true,
Balances: balances,
}
testserdes.EncodeDecodeBinary(t, a, new(Account))
}
func TestAccountStateBalanceValues(t *testing.T) {
asset1 := random.Uint256()
asset2 := random.Uint256()
as := Account{Balances: make(map[util.Uint256][]UnspentBalance)}
ref := 0
for i := 0; i < 10; i++ {
ref += i
as.Balances[asset1] = append(as.Balances[asset1], UnspentBalance{Value: util.Fixed8(i)})
as.Balances[asset2] = append(as.Balances[asset2], UnspentBalance{Value: util.Fixed8(i * 10)})
}
bVals := as.GetBalanceValues()
assert.Equal(t, util.Fixed8(ref), bVals[asset1])
assert.Equal(t, util.Fixed8(ref*10), bVals[asset2])
}

View file

@ -1,11 +0,0 @@
package transaction
//go:generate stringer -type=AttrUsage
// AttrUsage represents the purpose of the attribute.
type AttrUsage uint8
// List of valid attribute usages.
const (
DescriptionURL AttrUsage = 0x81
)

View file

@ -3,7 +3,6 @@ package transaction
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/io"
@ -11,50 +10,46 @@ import (
// Attribute represents a Transaction attribute.
type Attribute struct {
Usage AttrUsage
Type AttrType
Data []byte
}
// attrJSON is used for JSON I/O of Attribute.
type attrJSON struct {
Usage string `json:"usage"`
Type string `json:"type"`
Data string `json:"data"`
}
// DecodeBinary implements Serializable interface.
func (attr *Attribute) DecodeBinary(br *io.BinReader) {
attr.Usage = AttrUsage(br.ReadB())
attr.Type = AttrType(br.ReadB())
var datasize uint64
switch attr.Usage {
case DescriptionURL:
// It's not VarUint as per C# implementation, dunno why
var urllen = br.ReadB()
datasize = uint64(urllen)
/**
switch attr.Type {
default:
br.Err = fmt.Errorf("failed decoding TX attribute usage: 0x%2x", int(attr.Usage))
br.Err = fmt.Errorf("failed decoding TX attribute usage: 0x%2x", int(attr.Type))
return
}
*/
attr.Data = make([]byte, datasize)
br.ReadBytes(attr.Data)
}
// EncodeBinary implements Serializable interface.
func (attr *Attribute) EncodeBinary(bw *io.BinWriter) {
bw.WriteB(byte(attr.Usage))
switch attr.Usage {
case DescriptionURL:
bw.WriteB(byte(len(attr.Data)))
bw.WriteBytes(attr.Data)
bw.WriteB(byte(attr.Type))
switch attr.Type {
default:
bw.Err = fmt.Errorf("failed encoding TX attribute usage: 0x%2x", attr.Usage)
bw.Err = fmt.Errorf("failed encoding TX attribute usage: 0x%2x", attr.Type)
}
}
// MarshalJSON implements the json Marshaller interface.
func (attr *Attribute) MarshalJSON() ([]byte, error) {
return json.Marshal(attrJSON{
Usage: attr.Usage.String(),
Type: "", // attr.Type.String() when we're to have some real attributes
Data: base64.StdEncoding.EncodeToString(attr.Data),
})
}
@ -70,13 +65,13 @@ func (attr *Attribute) UnmarshalJSON(data []byte) error {
if err != nil {
return err
}
switch aj.Usage {
case "DescriptionURL":
attr.Usage = DescriptionURL
/**
switch aj.Type {
default:
return errors.New("wrong Usage")
return errors.New("wrong Type")
}
*/
attr.Data = binData
return nil
}

View file

@ -0,0 +1,10 @@
package transaction
//go:generate stringer -type=AttrType
// AttrType represents the purpose of the attribute.
type AttrType uint8
// List of valid attribute types (none for preview3).
//const (
//)

View file

@ -1,24 +0,0 @@
// Code generated by "stringer -type=AttrUsage"; DO NOT EDIT.
package transaction
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[DescriptionURL-129]
}
const _AttrUsage_name = "DescriptionURL"
var _AttrUsage_index = [...]uint8{0, 14}
func (i AttrUsage) String() string {
i -= 129
if i >= AttrUsage(len(_AttrUsage_index)-1) {
return "AttrUsage(" + strconv.FormatInt(int64(i+129), 10) + ")"
}
return _AttrUsage_name[_AttrUsage_index[i]:_AttrUsage_index[i+1]]
}

View file

@ -88,9 +88,6 @@ func (chain testChain) GetHeader(hash util.Uint256) (*block.Header, error) {
panic("TODO")
}
func (chain testChain) GetAccountState(util.Uint160) *state.Account {
panic("TODO")
}
func (chain testChain) GetNextBlockValidators() ([]*keys.PublicKey, error) {
panic("TODO")
}

View file

@ -365,18 +365,6 @@ func (c *Client) invokeSomething(method string, p request.RawParams, signers []t
p.Values = append(p.Values, signers)
}
if err := c.performRequest(method, p, resp); err != nil {
// Retry with old-fashioned hashes (see neo/neo-modules#260).
if signers != nil {
var hashes = make([]util.Uint160, len(signers))
for i := range signers {
hashes[i] = signers[i].Account
}
p.Values[len(p.Values)-1] = hashes
err = c.performRequest(method, p, resp)
if err == nil {
return resp, nil
}
}
return nil, err
}
return resp, nil