Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented rpc server method GetRawTransaction #135

Merged
merged 25 commits into from
Feb 20, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
41e27d7
Added utility function GetVarSize
dauTT Feb 10, 2019
79f41f9
1) Added Size method: this implied that Fixed8 implements now the ser…
dauTT Feb 10, 2019
a837151
Implemented Size or MarshalJSON method.
dauTT Feb 10, 2019
c280890
Added fee calculation
dauTT Feb 10, 2019
30d0a4a
Implemented rcp server method GetRawTransaction
dauTT Feb 10, 2019
6540cf8
Updated Tests
dauTT Feb 10, 2019
ba3393e
Fixed:
dauTT Feb 12, 2019
36b69e4
Simplified Size calculation
dauTT Feb 12, 2019
df11e05
1) Removed global variable blockchainDefault, configDefault
dauTT Feb 13, 2019
42590dc
Simplified GetVarSize Method
dauTT Feb 13, 2019
38528c5
Merge branch 'master' into dauTT/patch-5
dauTT Feb 14, 2019
9b91af1
Replaced ValueAtAndType with ValueWithType
dauTT Feb 14, 2019
04a25fe
Cosmetic changes + Added test case getrawtransaction_7
dauTT Feb 14, 2019
5bff6c4
Clean up Print statement
dauTT Feb 14, 2019
974e986
Filled up keys
dauTT Feb 17, 2019
087ea47
Aligned verbose logic with the C#-neo implementation
dauTT Feb 17, 2019
4b4822a
Implemented @Kim requests
dauTT Feb 17, 2019
94ac1d3
Small fixes
dauTT Feb 17, 2019
5b9f828
Fixed verbose logic
dauTT Feb 18, 2019
da3f83f
Replaced assert.NoError with require.NoError
dauTT Feb 18, 2019
a9d07e8
Merge branch 'master' into dauTT/patch-5
dauTT Feb 19, 2019
a8328ff
Merge branch 'master' into dauTT/patch-5
dauTT Feb 19, 2019
18b6b35
Fixed tests by adding context.Background() as argument
dauTT Feb 19, 2019
b576289
Merge branch 'master' into dauTT/patch-5
dauTT Feb 20, 2019
61b8e96
Fixed tests
dauTT Feb 20, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import (
"fmt"
"io/ioutil"
"os"
"sync"
"time"

"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/util"
"github.com/go-yaml/yaml"
"github.com/pkg/errors"
)
Expand All @@ -27,6 +30,10 @@ var (
// BuildTime the time and date the current version of the node built,
// set at build time.
BuildTime string

// ConfigDefault is the Config which is defined in the Load method.
configDefault *Config
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't use global variables

mu sync.Mutex
)

type (
Expand Down Expand Up @@ -104,17 +111,49 @@ func Load(path string, netMode NetMode) (Config, error) {
return Config{}, errors.Wrap(err, "Unable to read config")
}

config := Config{
config := &Config{
ProtocolConfiguration: ProtocolConfiguration{
SystemFee: SystemFee{},
},
ApplicationConfiguration: ApplicationConfiguration{},
}

err = yaml.Unmarshal(configData, &config)
setConfig(config)

err = yaml.Unmarshal(configData, &configDefault)
if err != nil {
return Config{}, errors.Wrap(err, "Problem unmarshaling config json data")
}

return config, nil
return *configDefault, nil
}

func setConfig(cfg *Config) {
mu.Lock()
configDefault = cfg
mu.Unlock()
}

// GetConfig returns a single instance of configDefault.
func GetConfig() *Config {
if configDefault == nil {
panic("configDefault is not available. Please load a configuration file.")
}
return configDefault
}

// TryGetValue returns the system fee base on transaction type.
func (s SystemFee) TryGetValue(txType transaction.TXType) util.Fixed8 {
switch txType {
case transaction.EnrollmentType:
return util.NewFixed8(s.EnrollmentTransaction)
case transaction.IssueType:
return util.NewFixed8(s.IssueTransaction)
case transaction.PublishType:
return util.NewFixed8(s.PublishTransaction)
case transaction.RegisterType:
return util.NewFixed8(s.RegisterTransaction)
default:
return util.NewFixed8(0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we must fix NewFixed8 method:

// NewFixed8 return a new Fixed8 type multiplied by decimals.
func NewFixed8(val int64) Fixed8 {
	return Fixed8(decimals * val)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or mb to:

// NewFixed8 return a new Fixed8 type multiplied by decimals.
func NewFixed8(val float64) Fixed8 {
	return Fixed8(int64(decimals * val))
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see there

}
}
33 changes: 26 additions & 7 deletions pkg/core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"fmt"
"sync"
"sync/atomic"
"time"

Expand All @@ -25,6 +26,10 @@ var (
genAmount = []int{8, 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
decrementInterval = 2000000
persistInterval = 1 * time.Second

// BlockchainDefault is the Blockchain which is defined in the NewBlockchain method.
blockchainDefault *Blockchain
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't use global variables

mu sync.Mutex
)

// Blockchain represents the blockchain.
Expand Down Expand Up @@ -69,16 +74,30 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration) (*Blockcha
blockCache: NewCache(),
verifyBlocks: false,
}
go bc.run()

if err := bc.init(); err != nil {
setBlockChain(bc)

go blockchainDefault.run()
if err := blockchainDefault.init(); err != nil {
return nil, err
}

return bc, nil
return blockchainDefault, nil
}

// GetBlockchain returns the blockchainDefault.
func GetBlockchain() *Blockchain {
return blockchainDefault
}

// setBlockChain sets the blockchainDefault.
func setBlockChain(bc *Blockchain) {
mu.Lock()
blockchainDefault = bc
mu.Unlock()
}

// GetBlockchainLevelDB returns blockchain based on configuration
// NewBlockchainLevelDB returns LevelDB blockchain based on configuration
func NewBlockchainLevelDB(cfg config.Config) (*Blockchain, error) {
store, err := storage.NewLevelDBStore(
cfg.ApplicationConfiguration.DataDirectoryPath,
Expand Down Expand Up @@ -148,7 +167,7 @@ func (bc *Blockchain) init() error {
headers := make([]*Header, 0)

for hash != targetHash {
header, err := bc.getHeader(hash)
header, err := bc.GetHeader(hash)
if err != nil {
return fmt.Errorf("could not get header %s: %s", hash, err)
}
Expand Down Expand Up @@ -483,7 +502,7 @@ func (bc *Blockchain) GetBlock(hash util.Uint256) (*Block, error) {
return block, nil
}

func (bc *Blockchain) getHeader(hash util.Uint256) (*Header, error) {
func (bc *Blockchain) GetHeader(hash util.Uint256) (*Header, error) {
b, err := bc.Get(storage.AppendPrefix(storage.DataBlock, hash.BytesReverse()))
if err != nil {
return nil, err
Expand All @@ -504,7 +523,7 @@ func (bc *Blockchain) HasTransaction(hash util.Uint256) bool {
// HasBlock return true if the blockchain contains the given
// block hash.
func (bc *Blockchain) HasBlock(hash util.Uint256) bool {
if header, err := bc.getHeader(hash); err == nil {
if header, err := bc.GetHeader(hash); err == nil {
return header.Index <= bc.BlockHeight()
}
return false
Expand Down
4 changes: 2 additions & 2 deletions pkg/core/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ func TestGetHeader(t *testing.T) {
assert.Nil(t, err)

hash := block.Hash()
header, err := bc.getHeader(hash)
header, err := bc.GetHeader(hash)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

require.NoError(t, err)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

t.Fatal(err)
}
assert.Equal(t, block.Header(), header)

block = newBlock(2)
hash = block.Hash()
_, err = bc.getHeader(block.Hash())
_, err = bc.GetHeader(block.Hash())
assert.NotNil(t, err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace with assert.Error(t, err)

}

Expand Down
3 changes: 3 additions & 0 deletions pkg/core/blockchainer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core

import (
"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/util"
)

Expand All @@ -13,10 +14,12 @@ type Blockchainer interface {
HeaderHeight() uint32
GetBlock(hash util.Uint256) (*Block, error)
GetHeaderHash(int) util.Uint256
GetHeader(hash util.Uint256) (*Header, error)
CurrentHeaderHash() util.Uint256
CurrentBlockHash() util.Uint256
HasBlock(util.Uint256) bool
HasTransaction(util.Uint256) bool
GetAssetState(util.Uint256) *AssetState
GetAccountState(util.Uint160) *AccountState
GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error)
}
59 changes: 59 additions & 0 deletions pkg/core/fee.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package core

import (
"github.com/CityOfZion/neo-go/config"
"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/util"
)

// References returns a map with input prevHash as key (util.Uint256)
// and transaction output as value from a transaction t.
// @TODO: unfortunately we couldn't attach this method to the Transaction struct in the
// transaction package because of a import cycle problem. Perhaps we should think to re-design
// the code base to avoid this situation.
func References(t *transaction.Transaction) map[util.Uint256]*transaction.Output {
references := make(map[util.Uint256]*transaction.Output)

for prevHash, inputs := range t.GroupInputsByPrevHash() {
bc := GetBlockchain()
if tx, _, err := bc.GetTransaction(prevHash); err != nil {
tx = nil
} else if tx != nil {
for _, in := range inputs {
references[in.PrevHash] = tx.Outputs[in.PrevIndex]
}
} else {
references = nil
}
}
return references
}

// FeePerByte returns network fee divided by the size of the transaction
func FeePerByte(t *transaction.Transaction) util.Fixed8 {
return NetworkFee(t).Div(int64(t.Size()))
}

// NetworkFee returns network fee
func NetworkFee(t *transaction.Transaction) util.Fixed8 {
inputAmount := util.NewFixed8(0)
for _, txOutput := range References(t) {
if txOutput.AssetID == utilityTokenTX().Hash() {
inputAmount.Add(txOutput.Amount)
}
}

outputAmount := util.NewFixed8(0)
for _, txOutput := range t.Outputs {
if txOutput.AssetID == utilityTokenTX().Hash() {
outputAmount.Add(txOutput.Amount)
}
}

return inputAmount.Sub(outputAmount).Sub(SystemFee(t))
}

// SystemFee returns system fee
func SystemFee(t *transaction.Transaction) util.Fixed8 {
return config.GetConfig().ProtocolConfiguration.SystemFee.TryGetValue(t.Type)
}
54 changes: 54 additions & 0 deletions pkg/core/fee_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package core

import (
"testing"

"github.com/CityOfZion/neo-go/config"
"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/util"
"github.com/stretchr/testify/assert"
)

func TestSize(t *testing.T) {
txID := "f999c36145a41306c846ea80290416143e8e856559818065be3f4e143c60e43a"
tx := getTestTransaction(txID, t)

assert.Equal(t, 283, tx.Size())
assert.Equal(t, 22, util.GetVarSize(tx.Attributes))
assert.Equal(t, 35, util.GetVarSize(tx.Inputs))
assert.Equal(t, 121, util.GetVarSize(tx.Outputs))
assert.Equal(t, 103, util.GetVarSize(tx.Scripts))
}

func getTestBlockchain(t *testing.T) *Blockchain {
net := config.ModeUnitTestNet
configPath := "../../config"
cfg, err := config.Load(configPath, net)
if err != nil {
t.Fatal("could not create levelDB chain", err)
}

// adjust datadirectory to point to the correct folder
cfg.ApplicationConfiguration.DataDirectoryPath = "../rpc/chains/unit_testnet"
chain, err := NewBlockchainLevelDB(cfg)
if err != nil {
t.Fatal("could not create levelDB chain", err)
}

return chain
}

func getTestTransaction(txID string, t *testing.T) *transaction.Transaction {
chain := getTestBlockchain(t)

txHash, err := util.Uint256DecodeString(txID)
if err != nil {
t.Fatalf("could not decode string %s to Uint256: err =%s", txID, err)
}

tx, _, err := chain.GetTransaction(txHash)
if err != nil {
t.Fatalf("Could not get transaction with hash=%s: err=%s", txHash, err)
}
return tx
}
54 changes: 54 additions & 0 deletions pkg/core/transaction/attr_usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,57 @@ const (
Remark14 AttrUsage = 0xfe
Remark15 AttrUsage = 0xff
)

// String implements the stringer interface.
func (attr AttrUsage) String() string {
attrLookup := map[AttrUsage]string{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mb we can move that to global?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

ContractHash: "ContractHash",
ECDH02: "ECDH02",
ECDH03: "ECDH03",
Script: "Script",
Vote: "Vote",
CertURL: "CertURL",
DescriptionURL: "DescriptionURL",
Description: "Description",

Hash1: "Hash1",
Hash2: "Hash2",
Hash3: "Hash3",
Hash4: "Hash4",
Hash5: "Hash5",
Hash6: "Hash6",
Hash7: "Hash7",
Hash8: "Hash8",
Hash9: "Hash9",
Hash10: "Hash10",
Hash11: "Hash11",
Hash12: "Hash12",
Hash13: "Hash13",
Hash14: "Hash14",
Hash15: "Hash15",

Remark: "Remark",
Remark1: "Remark1",
Remark2: "Remark2",
Remark3: "Remark3",
Remark4: "Remark4",
Remark5: "Remark5",
Remark6: "Remark6",
Remark7: "Remark7",
Remark8: "Remark8",
Remark9: "Remark9",
Remark10: "Remark10",
Remark11: "Remark11",
Remark12: "Remark12",
Remark13: "Remark13",
Remark14: "Remark14",
Remark15: "Remark15",
}

v, ok := attrLookup[attr]
if !ok {
return "Unkown Attribute"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if v, ok := attrLookup[attr]; ok {
  return v
}
return "Unkown Attribute"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


return v
}
Loading