pull/128/head
Minh Doan 6 years ago committed by Minh Doan
parent 5b6e91a6be
commit d32aa3826a
  1. 6
      core/chain_makers.go
  2. 2
      core/genesis.go
  3. 38
      core/types/block.go
  4. 7
      core/types/bloom9.go
  5. 2
      core/types/derive_sha.go
  6. 108
      core/types/transaction.go
  7. 10
      core/types/transaction_signing.go
  8. 16
      core/types/transaction_signing_test.go
  9. 4
      core/types/transaction_test.go
  10. 2
      node/node.go

@ -71,9 +71,9 @@ func (b *BlockGen) SetNonce(nonce types.BlockNonce) {
b.header.Nonce = nonce b.header.Nonce = nonce
} }
// SetShardID sets the shardId field of the generated block. // SetShardID sets the shardID field of the generated block.
func (b *BlockGen) SetShardID(shardId types.ShardID) { func (b *BlockGen) SetShardID(shardID types.ShardID) {
b.header.ShardID = shardId b.header.ShardID = shardID
} }
// AddTx adds a transaction to the generated block. If no coinbase has // AddTx adds a transaction to the generated block. If no coinbase has

@ -45,7 +45,7 @@ var errGenesisNoConfig = errors.New("genesis has no chain configuration")
type Genesis struct { type Genesis struct {
Config *params.ChainConfig `json:"config"` Config *params.ChainConfig `json:"config"`
Nonce uint64 `json:"nonce"` Nonce uint64 `json:"nonce"`
ShardID uint32 `json:"shardId"` ShardID uint32 `json:"shardID"`
Timestamp uint64 `json:"timestamp"` Timestamp uint64 `json:"timestamp"`
ExtraData []byte `json:"extraData"` ExtraData []byte `json:"extraData"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"` GasLimit uint64 `json:"gasLimit" gencodec:"required"`

@ -75,8 +75,6 @@ func (n *BlockNonce) UnmarshalText(input []byte) error {
return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) return hexutil.UnmarshalFixedText("BlockNonce", input, n[:])
} }
//go:generate gencodec -type Header -field-override headerMarshaling -out gen_header_json.go
// Header represents a block header in the Ethereum blockchain. // Header represents a block header in the Ethereum blockchain.
type Header struct { type Header struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"` ParentHash common.Hash `json:"parentHash" gencodec:"required"`
@ -93,7 +91,7 @@ type Header struct {
Extra []byte `json:"extraData" gencodec:"required"` Extra []byte `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash" gencodec:"required"` MixDigest common.Hash `json:"mixHash" gencodec:"required"`
Nonce BlockNonce `json:"nonce" gencodec:"required"` Nonce BlockNonce `json:"nonce" gencodec:"required"`
ShardID ShardID `json:"shardId" gencodec:"required"` ShardID ShardID `json:"shardID" gencodec:"required"`
} }
// field type overrides for gencodec // field type overrides for gencodec
@ -302,7 +300,7 @@ func (b *Block) GasUsed() uint64 { return b.header.GasUsed }
// Difficulty is the header difficulty. // Difficulty is the header difficulty.
func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) } func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
// TIme is header time. // Time is header time.
func (b *Block) Time() *big.Int { return new(big.Int).Set(b.header.Time) } func (b *Block) Time() *big.Int { return new(big.Int).Set(b.header.Time) }
// NumberU64 is the header number in uint64. // NumberU64 is the header number in uint64.
@ -316,14 +314,29 @@ func (b *Block) Nonce() uint64 { return binary.BigEndian.Uint64(b.header.Nonce[:
// ShardID is the header ShardID // ShardID is the header ShardID
func (b *Block) ShardID() uint32 { return binary.BigEndian.Uint32(b.header.ShardID[:]) } func (b *Block) ShardID() uint32 { return binary.BigEndian.Uint32(b.header.ShardID[:]) }
// Bloom returns header bloom.
func (b *Block) Bloom() Bloom { return b.header.Bloom } func (b *Block) Bloom() Bloom { return b.header.Bloom }
// Coinbase returns header coinbase.
func (b *Block) Coinbase() common.Address { return b.header.Coinbase } func (b *Block) Coinbase() common.Address { return b.header.Coinbase }
// Root returns header root.
func (b *Block) Root() common.Hash { return b.header.Root } func (b *Block) Root() common.Hash { return b.header.Root }
// ParentHash return header parent hash.
func (b *Block) ParentHash() common.Hash { return b.header.ParentHash } func (b *Block) ParentHash() common.Hash { return b.header.ParentHash }
// TxHash returns header tx hash.
func (b *Block) TxHash() common.Hash { return b.header.TxHash } func (b *Block) TxHash() common.Hash { return b.header.TxHash }
// ReceiptHash returns header receipt hash.
func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash } func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash }
// Extra returns header extra.
func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) } func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) }
// Header returns a copy of Header.
func (b *Block) Header() *Header { return CopyHeader(b.header) } func (b *Block) Header() *Header { return CopyHeader(b.header) }
// Body returns the non-header content of the block. // Body returns the non-header content of the block.
@ -348,6 +361,7 @@ func (c *writeCounter) Write(b []byte) (int, error) {
return len(b), nil return len(b), nil
} }
// CalcUncleHash returns rlp hash of uncles.
func CalcUncleHash(uncles []*Header) common.Hash { func CalcUncleHash(uncles []*Header) common.Hash {
return rlpHash(uncles) return rlpHash(uncles)
} }
@ -410,15 +424,21 @@ type blockSorter struct {
} }
// Len returns len of the blocks. // Len returns len of the blocks.
func (self blockSorter) Len() int { return len(self.blocks) } func (s blockSorter) Len() int {
return len(s.blocks)
}
// Swap swaps block i and block j. // Swap swaps block i and block j.
func (self blockSorter) Swap(i, j int) { func (s blockSorter) Swap(i, j int) {
self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i] s.blocks[i], s.blocks[j] = s.blocks[j], s.blocks[i]
} }
// Less checks if block i is less than block j. // Less checks if block i is less than block j.
func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) } func (s blockSorter) Less(i, j int) bool {
return s.by(s.blocks[i], s.blocks[j])
}
// Number checks if block b1 is less than block b2. // Number checks if block b1 is less than block b2.
func Number(b1, b2 *Block) bool { return b1.header.Number.Cmp(b2.header.Number) < 0 } func Number(b1, b2 *Block) bool {
return b1.header.Number.Cmp(b2.header.Number) < 0
}

@ -68,14 +68,17 @@ func (b Bloom) Big() *big.Int {
return new(big.Int).SetBytes(b[:]) return new(big.Int).SetBytes(b[:])
} }
// Bytes returns bytes of Bloom.
func (b Bloom) Bytes() []byte { func (b Bloom) Bytes() []byte {
return b[:] return b[:]
} }
// Test tests if an input may belong to the bloom.
func (b Bloom) Test(test *big.Int) bool { func (b Bloom) Test(test *big.Int) bool {
return BloomLookup(b, test) return BloomLookup(b, test)
} }
// TestBytes tests if the input represented by test []byte may belong to the bloom.
func (b Bloom) TestBytes(test []byte) bool { func (b Bloom) TestBytes(test []byte) bool {
return b.Test(new(big.Int).SetBytes(test)) return b.Test(new(big.Int).SetBytes(test))
@ -91,6 +94,7 @@ func (b *Bloom) UnmarshalText(input []byte) error {
return hexutil.UnmarshalFixedText("Bloom", input, b[:]) return hexutil.UnmarshalFixedText("Bloom", input, b[:])
} }
// CreateBloom creates a Bloom given the receipts.
func CreateBloom(receipts Receipts) Bloom { func CreateBloom(receipts Receipts) Bloom {
bin := new(big.Int) bin := new(big.Int)
for _, receipt := range receipts { for _, receipt := range receipts {
@ -100,6 +104,7 @@ func CreateBloom(receipts Receipts) Bloom {
return BytesToBloom(bin.Bytes()) return BytesToBloom(bin.Bytes())
} }
// LogsBloom ...
func LogsBloom(logs []*Log) *big.Int { func LogsBloom(logs []*Log) *big.Int {
bin := new(big.Int) bin := new(big.Int)
for _, log := range logs { for _, log := range logs {
@ -126,8 +131,10 @@ func bloom9(b []byte) *big.Int {
return r return r
} }
// Bloom9 type.
var Bloom9 = bloom9 var Bloom9 = bloom9
// BloomLookup checks if a topic may belong to the Bloom.
func BloomLookup(bin Bloom, topic bytesBacked) bool { func BloomLookup(bin Bloom, topic bytesBacked) bool {
bloom := bin.Big() bloom := bin.Big()
cmp := bloom9(topic.Bytes()) cmp := bloom9(topic.Bytes())

@ -24,11 +24,13 @@ import (
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
) )
// DerivableList is the interface of DerivableList.
type DerivableList interface { type DerivableList interface {
Len() int Len() int
GetRlp(i int) []byte GetRlp(i int) []byte
} }
// DeriveSha calculates the hash of the trie generated by DerivableList.
func DeriveSha(list DerivableList) common.Hash { func DeriveSha(list DerivableList) common.Hash {
keybuf := new(bytes.Buffer) keybuf := new(bytes.Buffer)
trie := new(trie.Trie) trie := new(trie.Trie)

@ -31,10 +31,12 @@ import (
//go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go //go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go
// Errors constants for Transaction.
var ( var (
ErrInvalidSig = errors.New("invalid transaction v, r, s values") ErrInvalidSig = errors.New("invalid transaction v, r, s values")
) )
// Transaction struct.
type Transaction struct { type Transaction struct {
data txdata data txdata
// caches // caches
@ -45,7 +47,7 @@ type Transaction struct {
type txdata struct { type txdata struct {
AccountNonce uint64 `json:"nonce" gencodec:"required"` AccountNonce uint64 `json:"nonce" gencodec:"required"`
ShardID uint32 `json:"shardId" gencodec:"required"` ShardID uint32 `json:"shardID" gencodec:"required"`
Price *big.Int `json:"gasPrice" gencodec:"required"` Price *big.Int `json:"gasPrice" gencodec:"required"`
GasLimit uint64 `json:"gas" gencodec:"required"` GasLimit uint64 `json:"gas" gencodec:"required"`
Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation
@ -72,22 +74,24 @@ type txdataMarshaling struct {
S *hexutil.Big S *hexutil.Big
} }
func NewTransaction(nonce uint64, to common.Address, shardId uint32, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { // NewTransaction returns new transaction.
return newTransaction(nonce, &to, shardId, amount, gasLimit, gasPrice, data) func NewTransaction(nonce uint64, to common.Address, shardID uint32, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
return newTransaction(nonce, &to, shardID, amount, gasLimit, gasPrice, data)
} }
func NewContractCreation(nonce uint64, shardId uint32, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { // NewContractCreation returns contract transaction.
return newTransaction(nonce, nil, shardId, amount, gasLimit, gasPrice, data) func NewContractCreation(nonce uint64, shardID uint32, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
return newTransaction(nonce, nil, shardID, amount, gasLimit, gasPrice, data)
} }
func newTransaction(nonce uint64, to *common.Address, shardId uint32, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { func newTransaction(nonce uint64, to *common.Address, shardID uint32, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
if len(data) > 0 { if len(data) > 0 {
data = common.CopyBytes(data) data = common.CopyBytes(data)
} }
d := txdata{ d := txdata{
AccountNonce: nonce, AccountNonce: nonce,
Recipient: to, Recipient: to,
ShardID: shardId, ShardID: shardID,
Payload: data, Payload: data,
Amount: new(big.Int), Amount: new(big.Int),
GasLimit: gasLimit, GasLimit: gasLimit,
@ -106,9 +110,9 @@ func newTransaction(nonce uint64, to *common.Address, shardId uint32, amount *bi
return &Transaction{data: d} return &Transaction{data: d}
} }
// ChainId returns which chain id this transaction was signed for (if at all) // ChainID returns which chain id this transaction was signed for (if at all)
func (tx *Transaction) ChainId() *big.Int { func (tx *Transaction) ChainID() *big.Int {
return deriveChainId(tx.data.V) return deriveChainID(tx.data.V)
} }
// Protected returns whether the transaction is protected from replay protection. // Protected returns whether the transaction is protected from replay protection.
@ -160,7 +164,7 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
if withSignature { if withSignature {
var V byte var V byte
if isProtectedV(dec.V) { if isProtectedV(dec.V) {
chainID := deriveChainId(dec.V).Uint64() chainID := deriveChainID(dec.V).Uint64()
V = byte(dec.V.Uint64() - 35 - 2*chainID) V = byte(dec.V.Uint64() - 35 - 2*chainID)
} else { } else {
V = byte(dec.V.Uint64() - 27) V = byte(dec.V.Uint64() - 27)
@ -174,12 +178,35 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
return nil return nil
} }
func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) } // Data returns data payload of Transaction.
func (tx *Transaction) Gas() uint64 { return tx.data.GasLimit } func (tx *Transaction) Data() []byte {
func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) } return common.CopyBytes(tx.data.Payload)
func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) } }
func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce }
func (tx *Transaction) CheckNonce() bool { return true } // Gas returns gas of Transaction.
func (tx *Transaction) Gas() uint64 {
return tx.data.GasLimit
}
// GasPrice returns gas price of Transaction.
func (tx *Transaction) GasPrice() *big.Int {
return new(big.Int).Set(tx.data.Price)
}
// Value returns data payload of Transaction.
func (tx *Transaction) Value() *big.Int {
return new(big.Int).Set(tx.data.Amount)
}
// Nonce returns account nonce from Transaction.
func (tx *Transaction) Nonce() uint64 {
return tx.data.AccountNonce
}
// CheckNonce returns check nonce from Transaction.
func (tx *Transaction) CheckNonce() bool {
return true
}
// To returns the recipient address of the transaction. // To returns the recipient address of the transaction.
// It returns nil if the transaction is a contract creation. // It returns nil if the transaction is a contract creation.
@ -409,11 +436,42 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *b
} }
} }
func (m Message) From() common.Address { return m.from } // From returns from address from Message.
func (m Message) To() *common.Address { return m.to } func (m Message) From() common.Address {
func (m Message) GasPrice() *big.Int { return m.gasPrice } return m.from
func (m Message) Value() *big.Int { return m.amount } }
func (m Message) Gas() uint64 { return m.gasLimit }
func (m Message) Nonce() uint64 { return m.nonce } // To returns to address from Message.
func (m Message) Data() []byte { return m.data } func (m Message) To() *common.Address {
func (m Message) CheckNonce() bool { return m.checkNonce } return m.to
}
// GasPrice returns gas price from Message.
func (m Message) GasPrice() *big.Int {
return m.gasPrice
}
// Value returns the value amount from Message.
func (m Message) Value() *big.Int {
return m.amount
}
// Gas returns gas limit of the Message.
func (m Message) Gas() uint64 {
return m.gasLimit
}
// Nonce returns Nonce of the Message.
func (m Message) Nonce() uint64 {
return m.nonce
}
// Data return data of the Message.
func (m Message) Data() []byte {
return m.data
}
// CheckNonce returns checkNonce of Message.
func (m Message) CheckNonce() bool {
return m.checkNonce
}

@ -29,7 +29,7 @@ import (
// Constants for transaction signing. // Constants for transaction signing.
var ( var (
ErrInvalidChainId = errors.New("invalid chain id for signer") ErrInvalidChainID = errors.New("invalid chain id for signer")
) )
// sigCache is used to cache the derived sender and contains // sigCache is used to cache the derived sender and contains
@ -129,8 +129,8 @@ func (s EIP155Signer) Sender(tx *Transaction) (common.Address, error) {
if !tx.Protected() { if !tx.Protected() {
return HomesteadSigner{}.Sender(tx) return HomesteadSigner{}.Sender(tx)
} }
if tx.ChainId().Cmp(s.chainId) != 0 { if tx.ChainID().Cmp(s.chainId) != 0 {
return common.Address{}, ErrInvalidChainId return common.Address{}, ErrInvalidChainID
} }
V := new(big.Int).Sub(tx.data.V, s.chainIdMul) V := new(big.Int).Sub(tx.data.V, s.chainIdMul)
V.Sub(V, big8) V.Sub(V, big8)
@ -247,8 +247,8 @@ func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool) (commo
return addr, nil return addr, nil
} }
// deriveChainId derives the chain id from the given v parameter // deriveChainID derives the chain id from the given v parameter
func deriveChainId(v *big.Int) *big.Int { func deriveChainID(v *big.Int) *big.Int {
if v.BitLen() <= 64 { if v.BitLen() <= 64 {
v := v.Uint64() v := v.Uint64()
if v == 27 || v == 28 { if v == 27 || v == 28 {

@ -43,7 +43,7 @@ func TestEIP155Signing(t *testing.T) {
} }
} }
func TestEIP155ChainId(t *testing.T) { func TestEIP155ChainID(t *testing.T) {
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
addr := crypto.PubkeyToAddress(key.PublicKey) addr := crypto.PubkeyToAddress(key.PublicKey)
@ -56,8 +56,8 @@ func TestEIP155ChainId(t *testing.T) {
t.Fatal("expected tx to be protected") t.Fatal("expected tx to be protected")
} }
if tx.ChainId().Cmp(signer.chainId) != 0 { if tx.ChainID().Cmp(signer.chainId) != 0 {
t.Error("expected chainId to be", signer.chainId, "got", tx.ChainId()) t.Error("expected chainId to be", signer.chainId, "got", tx.ChainID())
} }
tx = NewTransaction(0, addr, 0, new(big.Int), 0, new(big.Int), nil) tx = NewTransaction(0, addr, 0, new(big.Int), 0, new(big.Int), nil)
@ -70,12 +70,12 @@ func TestEIP155ChainId(t *testing.T) {
t.Error("didn't expect tx to be protected") t.Error("didn't expect tx to be protected")
} }
if tx.ChainId().Sign() != 0 { if tx.ChainID().Sign() != 0 {
t.Error("expected chain id to be 0 got", tx.ChainId()) t.Error("expected chain id to be 0 got", tx.ChainID())
} }
} }
func TestChainId(t *testing.T) { func TestChainID(t *testing.T) {
key, _ := defaultTestKey() key, _ := defaultTestKey()
tx := NewTransaction(0, common.Address{}, 0, new(big.Int), 0, new(big.Int), nil) tx := NewTransaction(0, common.Address{}, 0, new(big.Int), 0, new(big.Int), nil)
@ -87,8 +87,8 @@ func TestChainId(t *testing.T) {
} }
_, err = Sender(NewEIP155Signer(big.NewInt(2)), tx) _, err = Sender(NewEIP155Signer(big.NewInt(2)), tx)
if err != ErrInvalidChainId { if err != ErrInvalidChainID {
t.Error("expected error:", ErrInvalidChainId) t.Error("expected error:", ErrInvalidChainID)
} }
_, err = Sender(NewEIP155Signer(big.NewInt(1)), tx) _, err = Sender(NewEIP155Signer(big.NewInt(1)), tx)

@ -172,8 +172,8 @@ func TestTransactionJSON(t *testing.T) {
if tx.Hash() != parsedTx.Hash() { if tx.Hash() != parsedTx.Hash() {
t.Errorf("parsed tx differs from original tx, want %v, got %v", tx, parsedTx) t.Errorf("parsed tx differs from original tx, want %v, got %v", tx, parsedTx)
} }
if tx.ChainId().Cmp(parsedTx.ChainId()) != 0 { if tx.ChainID().Cmp(parsedTx.ChainID()) != 0 {
t.Errorf("invalid chain id, want %d, got %d", tx.ChainId(), parsedTx.ChainId()) t.Errorf("invalid chain id, want %d, got %d", tx.ChainID(), parsedTx.ChainID())
} }
} }
} }

@ -297,7 +297,7 @@ func New(consensus *bft.Consensus, db *hdb.LDBDatabase, selfPeer p2p.Peer) *Node
database := hdb.NewMemDatabase() database := hdb.NewMemDatabase()
chainConfig := params.TestChainConfig chainConfig := params.TestChainConfig
chainConfig.ChainID = big.NewInt(int64(node.Consensus.ShardID)) // Use ChainId as piggybacked ShardID chainConfig.ChainID = big.NewInt(int64(node.Consensus.ShardID)) // Use ChainID as piggybacked ShardID
gspec := core.Genesis{ gspec := core.Genesis{
Config: chainConfig, Config: chainConfig,
Alloc: genesisAloc, Alloc: genesisAloc,

Loading…
Cancel
Save