pull/128/head
Minh Doan 6 years ago
parent d32aa3826a
commit 5f09b7aee7
  1. 4
      core/blockchain.go
  2. 3
      core/events.go
  3. 1
      core/genesis.go
  4. 4
      core/headerchain.go
  5. 2
      core/state_transition.go
  6. 1
      core/tx_pool.go
  7. 8
      core/tx_pool_test.go
  8. 4
      core/types/transaction.go
  9. 40
      core/types/transaction_signing.go
  10. 4
      core/types/transaction_signing_test.go
  11. 5
      core/vm/logger_test.go
  12. 1
      core/vm/runtime/env.go
  13. 11
      core/vm/runtime/runtime_test.go

@ -48,8 +48,10 @@ import (
) )
var ( var (
// blockInsertTimer
blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil) blockInsertTimer = metrics.NewRegisteredTimer("chain/inserts", nil)
// ErrNoGenesis is the error when there is no genesis.
ErrNoGenesis = errors.New("Genesis not found in chain") ErrNoGenesis = errors.New("Genesis not found in chain")
) )
@ -189,6 +191,7 @@ func NewBlockChain(db hdb.Database, cacheConfig *CacheConfig, chainConfig *param
return bc, nil return bc, nil
} }
// ValidateNewBlock validates new block.
func (bc *BlockChain) ValidateNewBlock(block *types.Block, address common.Address) error { func (bc *BlockChain) ValidateNewBlock(block *types.Block, address common.Address) error {
state, err := state.New(bc.CurrentBlock().Root(), bc.stateCache) state, err := state.New(bc.CurrentBlock().Root(), bc.stateCache)
@ -734,6 +737,7 @@ func (bc *BlockChain) procFutureBlocks() {
// WriteStatus status of write // WriteStatus status of write
type WriteStatus byte type WriteStatus byte
// Constants for WriteStatus
const ( const (
NonStatTy WriteStatus = iota NonStatTy WriteStatus = iota
CanonStatTy CanonStatTy

@ -35,14 +35,17 @@ type NewMinedBlockEvent struct{ Block *types.Block }
// RemovedLogsEvent is posted when a reorg happens // RemovedLogsEvent is posted when a reorg happens
type RemovedLogsEvent struct{ Logs []*types.Log } type RemovedLogsEvent struct{ Logs []*types.Log }
// ChainEvent is the struct of chain event.
type ChainEvent struct { type ChainEvent struct {
Block *types.Block Block *types.Block
Hash common.Hash Hash common.Hash
Logs []*types.Log Logs []*types.Log
} }
// ChainSideEvent is chain side event.
type ChainSideEvent struct { type ChainSideEvent struct {
Block *types.Block Block *types.Block
} }
// ChainHeadEvent is the struct of chain head event.
type ChainHeadEvent struct{ Block *types.Block } type ChainHeadEvent struct{ Block *types.Block }

@ -64,6 +64,7 @@ type Genesis struct {
// GenesisAlloc specifies the initial state that is part of the genesis block. // GenesisAlloc specifies the initial state that is part of the genesis block.
type GenesisAlloc map[common.Address]GenesisAccount type GenesisAlloc map[common.Address]GenesisAccount
// UnmarshalJSON is to deserialize the data into GenesisAlloc.
func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
m := make(map[common.UnprefixedAddress]GenesisAccount) m := make(map[common.UnprefixedAddress]GenesisAccount)
if err := json.Unmarshal(data, &m); err != nil { if err := json.Unmarshal(data, &m); err != nil {

@ -204,6 +204,7 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
// header writes should be protected by the parent chain mutex individually. // header writes should be protected by the parent chain mutex individually.
type WhCallback func(*types.Header) error type WhCallback func(*types.Header) error
// ValidateHeaderChain validates header chain.
func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) (int, error) { func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) (int, error) {
// Do a sanity check that the provided chain is actually ordered and linked // Do a sanity check that the provided chain is actually ordered and linked
for i := 1; i < len(chain); i++ { for i := 1; i < len(chain); i++ {
@ -330,9 +331,8 @@ func (hc *HeaderChain) GetAncestor(hash common.Hash, number, ancestor uint64, ma
// in this case it is cheaper to just read the header // in this case it is cheaper to just read the header
if header := hc.GetHeader(hash, number); header != nil { if header := hc.GetHeader(hash, number); header != nil {
return header.ParentHash, number - 1 return header.ParentHash, number - 1
} else {
return common.Hash{}, 0
} }
return common.Hash{}, 0
} }
for ancestor != 0 { for ancestor != 0 {
if rawdb.ReadCanonicalHash(hc.chainDb, number) == hash { if rawdb.ReadCanonicalHash(hc.chainDb, number) == hash {

@ -33,7 +33,7 @@ var (
) )
/* /*
The State Transitioning Model StateTransition is the State Transitioning Model which is described as follows:
A state transition is a change made when a transaction is applied to the current world state A state transition is a change made when a transaction is applied to the current world state
The state transitioning model does all the necessary work to work out a valid new state root. The state transitioning model does all the necessary work to work out a valid new state root.

@ -104,6 +104,7 @@ var (
// TxStatus is the current status of a transaction as seen by the pool. // TxStatus is the current status of a transaction as seen by the pool.
type TxStatus uint type TxStatus uint
// Constants for TxStatus.
const ( const (
TxStatusUnknown TxStatus = iota TxStatusUnknown TxStatus = iota
TxStatusQueued TxStatusQueued

@ -1053,13 +1053,13 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
// Create transaction (both pending and queued) with a linearly growing gasprice // Create transaction (both pending and queued) with a linearly growing gasprice
for i := uint64(0); i < 500; i++ { for i := uint64(0); i < 500; i++ {
// Add pending // Add pending
p_tx := pricedTransaction(i, 100000, big.NewInt(int64(i)), keys[2]) pTx := pricedTransaction(i, 100000, big.NewInt(int64(i)), keys[2])
if err := pool.AddLocal(p_tx); err != nil { if err := pool.AddLocal(pTx); err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Add queued // Add queued
q_tx := pricedTransaction(i+501, 100000, big.NewInt(int64(i)), keys[2]) qTx := pricedTransaction(i+501, 100000, big.NewInt(int64(i)), keys[2])
if err := pool.AddLocal(q_tx); err != nil { if err := pool.AddLocal(qTx); err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }

@ -281,6 +281,7 @@ func (tx *Transaction) Cost() *big.Int {
return total return total
} }
// RawSignatureValues return raw signature values.
func (tx *Transaction) RawSignatureValues() (*big.Int, *big.Int, *big.Int) { func (tx *Transaction) RawSignatureValues() (*big.Int, *big.Int, *big.Int) {
return tx.data.V, tx.data.R, tx.data.S return tx.data.V, tx.data.R, tx.data.S
} }
@ -335,10 +336,12 @@ func (s TxByPrice) Len() int { return len(s) }
func (s TxByPrice) Less(i, j int) bool { return s[i].data.Price.Cmp(s[j].data.Price) > 0 } func (s TxByPrice) Less(i, j int) bool { return s[i].data.Price.Cmp(s[j].data.Price) > 0 }
func (s TxByPrice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s TxByPrice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Push pushes a transaction.
func (s *TxByPrice) Push(x interface{}) { func (s *TxByPrice) Push(x interface{}) {
*s = append(*s, x.(*Transaction)) *s = append(*s, x.(*Transaction))
} }
// Pop pops a transaction.
func (s *TxByPrice) Pop() interface{} { func (s *TxByPrice) Pop() interface{} {
old := *s old := *s
n := len(old) n := len(old)
@ -423,6 +426,7 @@ type Message struct {
checkNonce bool checkNonce bool
} }
// NewMessage returns new message.
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message { func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message {
return Message{ return Message{
from: from, from: from,

@ -103,36 +103,39 @@ type Signer interface {
Equal(Signer) bool Equal(Signer) bool
} }
// EIP155Transaction implements Signer using the EIP155 rules. // EIP155Signer implements Signer using the EIP155 rules.
type EIP155Signer struct { type EIP155Signer struct {
chainId, chainIdMul *big.Int chainID, chainIDMul *big.Int
} }
func NewEIP155Signer(chainId *big.Int) EIP155Signer { // NewEIP155Signer creates a EIP155Signer given chainID.
if chainId == nil { func NewEIP155Signer(chainID *big.Int) EIP155Signer {
chainId = new(big.Int) if chainID == nil {
chainID = new(big.Int)
} }
return EIP155Signer{ return EIP155Signer{
chainId: chainId, chainID: chainID,
chainIdMul: new(big.Int).Mul(chainId, big.NewInt(2)), chainIDMul: new(big.Int).Mul(chainID, big.NewInt(2)),
} }
} }
// Equal checks if the given EIP155Signer is equal to another Signer.
func (s EIP155Signer) Equal(s2 Signer) bool { func (s EIP155Signer) Equal(s2 Signer) bool {
eip155, ok := s2.(EIP155Signer) eip155, ok := s2.(EIP155Signer)
return ok && eip155.chainId.Cmp(s.chainId) == 0 return ok && eip155.chainID.Cmp(s.chainID) == 0
} }
var big8 = big.NewInt(8) var big8 = big.NewInt(8)
// Sender returns the sender address of the given signer.
func (s EIP155Signer) Sender(tx *Transaction) (common.Address, error) { 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)
return recoverPlain(s.Hash(tx), tx.data.R, tx.data.S, V, true) return recoverPlain(s.Hash(tx), tx.data.R, tx.data.S, V, true)
} }
@ -144,9 +147,9 @@ func (s EIP155Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
if s.chainId.Sign() != 0 { if s.chainID.Sign() != 0 {
V = big.NewInt(int64(sig[64] + 35)) V = big.NewInt(int64(sig[64] + 35))
V.Add(V, s.chainIdMul) V.Add(V, s.chainIDMul)
} }
return R, S, V, nil return R, S, V, nil
} }
@ -161,15 +164,16 @@ func (s EIP155Signer) Hash(tx *Transaction) common.Hash {
tx.data.Recipient, tx.data.Recipient,
tx.data.Amount, tx.data.Amount,
tx.data.Payload, tx.data.Payload,
s.chainId, uint(0), uint(0), s.chainID, uint(0), uint(0),
}) })
} }
// HomesteadTransaction implements TransactionInterface using the // HomesteadSigner implements TransactionInterface using the
// homestead rules. // homestead rules.
type HomesteadSigner struct{ FrontierSigner } type HomesteadSigner struct{ FrontierSigner }
func (s HomesteadSigner) Equal(s2 Signer) bool { // Equal checks if it is equal to s2 signer.
func (hs HomesteadSigner) Equal(s2 Signer) bool {
_, ok := s2.(HomesteadSigner) _, ok := s2.(HomesteadSigner)
return ok return ok
} }
@ -180,13 +184,16 @@ func (hs HomesteadSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v
return hs.FrontierSigner.SignatureValues(tx, sig) return hs.FrontierSigner.SignatureValues(tx, sig)
} }
// Sender returns the address of the sender.
func (hs HomesteadSigner) Sender(tx *Transaction) (common.Address, error) { func (hs HomesteadSigner) Sender(tx *Transaction) (common.Address, error) {
return recoverPlain(hs.Hash(tx), tx.data.R, tx.data.S, tx.data.V, true) return recoverPlain(hs.Hash(tx), tx.data.R, tx.data.S, tx.data.V, true)
} }
// FrontierSigner ...
type FrontierSigner struct{} type FrontierSigner struct{}
func (s FrontierSigner) Equal(s2 Signer) bool { // Equal checks if the s2 signer is equal to the given signer.
func (fs FrontierSigner) Equal(s2 Signer) bool {
_, ok := s2.(FrontierSigner) _, ok := s2.(FrontierSigner)
return ok return ok
} }
@ -216,6 +223,7 @@ func (fs FrontierSigner) Hash(tx *Transaction) common.Hash {
}) })
} }
// Sender returns the sender address of the given transaction.
func (fs FrontierSigner) Sender(tx *Transaction) (common.Address, error) { func (fs FrontierSigner) Sender(tx *Transaction) (common.Address, error) {
return recoverPlain(fs.Hash(tx), tx.data.R, tx.data.S, tx.data.V, false) return recoverPlain(fs.Hash(tx), tx.data.R, tx.data.S, tx.data.V, false)
} }

@ -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)

@ -46,7 +46,10 @@ type dummyStatedb struct {
state.StateDB state.StateDB
} }
func (dummyStatedb) GetRefund() uint64 { return 1337 } // GetRefund ...
func (*dummyStatedb) GetRefund() uint64 {
return 1337
}
func TestStoreCapture(t *testing.T) { func TestStoreCapture(t *testing.T) {
var ( var (

@ -22,6 +22,7 @@ import (
"github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/core/vm"
) )
// NewEnv returns new EVM.
func NewEnv(cfg *Config) *vm.EVM { func NewEnv(cfg *Config) *vm.EVM {
context := vm.Context{ context := vm.Context{
CanTransfer: core.CanTransfer, CanTransfer: core.CanTransfer,

@ -149,7 +149,8 @@ func BenchmarkCall(b *testing.B) {
} }
} }
} }
func benchmarkEVM_Create(bench *testing.B, code string) {
func benchmarkEVMCreate(bench *testing.B, code string) {
var ( var (
statedb, _ = state.New(common.Hash{}, state.NewDatabase(db.NewMemDatabase())) statedb, _ = state.New(common.Hash{}, state.NewDatabase(db.NewMemDatabase()))
sender = common.BytesToAddress([]byte("sender")) sender = common.BytesToAddress([]byte("sender"))
@ -189,17 +190,17 @@ func benchmarkEVM_Create(bench *testing.B, code string) {
func BenchmarkEVM_CREATE_500(bench *testing.B) { func BenchmarkEVM_CREATE_500(bench *testing.B) {
// initcode size 500K, repeatedly calls CREATE and then modifies the mem contents // initcode size 500K, repeatedly calls CREATE and then modifies the mem contents
benchmarkEVM_Create(bench, "5b6207a120600080f0600152600056") benchmarkEVMCreate(bench, "5b6207a120600080f0600152600056")
} }
func BenchmarkEVM_CREATE2_500(bench *testing.B) { func BenchmarkEVM_CREATE2_500(bench *testing.B) {
// initcode size 500K, repeatedly calls CREATE2 and then modifies the mem contents // initcode size 500K, repeatedly calls CREATE2 and then modifies the mem contents
benchmarkEVM_Create(bench, "5b586207a120600080f5600152600056") benchmarkEVMCreate(bench, "5b586207a120600080f5600152600056")
} }
func BenchmarkEVM_CREATE_1200(bench *testing.B) { func BenchmarkEVM_CREATE_1200(bench *testing.B) {
// initcode size 1200K, repeatedly calls CREATE and then modifies the mem contents // initcode size 1200K, repeatedly calls CREATE and then modifies the mem contents
benchmarkEVM_Create(bench, "5b62124f80600080f0600152600056") benchmarkEVMCreate(bench, "5b62124f80600080f0600152600056")
} }
func BenchmarkEVM_CREATE2_1200(bench *testing.B) { func BenchmarkEVM_CREATE2_1200(bench *testing.B) {
// initcode size 1200K, repeatedly calls CREATE2 and then modifies the mem contents // initcode size 1200K, repeatedly calls CREATE2 and then modifies the mem contents
benchmarkEVM_Create(bench, "5b5862124f80600080f5600152600056") benchmarkEVMCreate(bench, "5b5862124f80600080f5600152600056")
} }

Loading…
Cancel
Save