aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/block_processor.go5
-rw-r--r--core/error.go22
-rw-r--r--core/execution.go2
-rw-r--r--core/state_transition.go2
-rw-r--r--core/types/transaction.go18
-rw-r--r--core/types/transaction_test.go6
-rw-r--r--core/vm/errors.go24
-rw-r--r--core/vm/vm.go4
-rw-r--r--rpc/api/eth.go26
-rw-r--r--rpc/api/parsing.go33
-rw-r--r--rpc/api/utils.go1
-rw-r--r--tests/init.go5
-rw-r--r--xeth/xeth.go3
13 files changed, 87 insertions, 64 deletions
diff --git a/core/block_processor.go b/core/block_processor.go
index e7ad059c3..660c917e4 100644
--- a/core/block_processor.go
+++ b/core/block_processor.go
@@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
@@ -72,7 +73,7 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated
cb := statedb.GetStateObject(coinbase.Address())
_, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, header), tx, cb)
- if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err) || IsInvalidTxErr(err)) {
+ if err != nil && err != vm.OutOfGasError {
return nil, nil, err
}
@@ -118,7 +119,7 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state
statedb.StartRecord(tx.Hash(), block.Hash(), i)
receipt, txGas, err := self.ApplyTransaction(coinbase, statedb, header, tx, totalUsedGas, transientProcess)
- if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err) || IsInvalidTxErr(err)) {
+ if err != nil && err != vm.OutOfGasError {
return nil, err
}
diff --git a/core/error.go b/core/error.go
index 3f3c350df..fb64d09b2 100644
--- a/core/error.go
+++ b/core/error.go
@@ -30,7 +30,6 @@ func ParentError(hash common.Hash) error {
func IsParentErr(err error) bool {
_, ok := err.(*ParentErr)
-
return ok
}
@@ -48,7 +47,6 @@ func UncleError(format string, v ...interface{}) error {
func IsUncleErr(err error) bool {
_, ok := err.(*UncleErr)
-
return ok
}
@@ -67,7 +65,6 @@ func ValidationError(format string, v ...interface{}) *ValidationErr {
func IsValidationErr(err error) bool {
_, ok := err.(*ValidationErr)
-
return ok
}
@@ -86,7 +83,6 @@ func NonceError(is, exp uint64) *NonceErr {
func IsNonceErr(err error) bool {
_, ok := err.(*NonceErr)
-
return ok
}
@@ -121,24 +117,6 @@ func InvalidTxError(err error) *InvalidTxErr {
func IsInvalidTxErr(err error) bool {
_, ok := err.(*InvalidTxErr)
-
- return ok
-}
-
-type OutOfGasErr struct {
- Message string
-}
-
-func OutOfGasError() *OutOfGasErr {
- return &OutOfGasErr{Message: "Out of gas"}
-}
-func (self *OutOfGasErr) Error() string {
- return self.Message
-}
-
-func IsOutOfGasErr(err error) bool {
- _, ok := err.(*OutOfGasErr)
-
return ok
}
diff --git a/core/execution.go b/core/execution.go
index 9fb0210de..a8c4ffb6d 100644
--- a/core/execution.go
+++ b/core/execution.go
@@ -53,7 +53,7 @@ func (self *Execution) exec(contextAddr *common.Address, code []byte, caller vm.
if env.Depth() > int(params.CallCreateDepth.Int64()) {
caller.ReturnGas(self.Gas, self.price)
- return nil, vm.DepthError{}
+ return nil, vm.DepthError
}
vsnapshot := env.State().Copy()
diff --git a/core/state_transition.go b/core/state_transition.go
index 5611ffd0f..465000e87 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -122,7 +122,7 @@ func (self *StateTransition) To() *state.StateObject {
func (self *StateTransition) UseGas(amount *big.Int) error {
if self.gas.Cmp(amount) < 0 {
- return OutOfGasError()
+ return vm.OutOfGasError
}
self.gas.Sub(self.gas, amount)
diff --git a/core/types/transaction.go b/core/types/transaction.go
index 95deac36e..c381fc5f3 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -116,11 +116,21 @@ func (tx *Transaction) To() *common.Address {
}
}
+// Hash hashes the RLP encoding of tx.
+// It uniquely identifies the transaction.
func (tx *Transaction) Hash() common.Hash {
if hash := tx.hash.Load(); hash != nil {
return hash.(common.Hash)
}
- v := rlpHash([]interface{}{
+ v := rlpHash(tx)
+ tx.hash.Store(v)
+ return v
+}
+
+// SigHash returns the hash to be signed by the sender.
+// It does not uniquely identify the transaction.
+func (tx *Transaction) SigHash() common.Hash {
+ return rlpHash([]interface{}{
tx.data.AccountNonce,
tx.data.Price,
tx.data.GasLimit,
@@ -128,8 +138,6 @@ func (tx *Transaction) Hash() common.Hash {
tx.data.Amount,
tx.data.Payload,
})
- tx.hash.Store(v)
- return v
}
func (tx *Transaction) Size() common.StorageSize {
@@ -180,7 +188,7 @@ func (tx *Transaction) publicKey() ([]byte, error) {
sig[64] = tx.data.V - 27
// recover the public key from the signature
- hash := tx.Hash()
+ hash := tx.SigHash()
pub, err := crypto.Ecrecover(hash[:], sig)
if err != nil {
glog.V(logger.Error).Infof("Could not get pubkey from signature: ", err)
@@ -204,7 +212,7 @@ func (tx *Transaction) WithSignature(sig []byte) (*Transaction, error) {
}
func (tx *Transaction) SignECDSA(prv *ecdsa.PrivateKey) (*Transaction, error) {
- h := tx.Hash()
+ h := tx.SigHash()
sig, err := crypto.Sign(h[:], prv)
if err != nil {
return nil, err
diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go
index dd9c5e87b..c9da4b73b 100644
--- a/core/types/transaction_test.go
+++ b/core/types/transaction_test.go
@@ -34,11 +34,11 @@ var (
)
)
-func TestTransactionHash(t *testing.T) {
- if emptyTx.Hash() != common.HexToHash("c775b99e7ad12f50d819fcd602390467e28141316969f4b57f0626f74fe3b386") {
+func TestTransactionSigHash(t *testing.T) {
+ if emptyTx.SigHash() != common.HexToHash("c775b99e7ad12f50d819fcd602390467e28141316969f4b57f0626f74fe3b386") {
t.Errorf("empty transaction hash mismatch, got %x", emptyTx.Hash())
}
- if rightvrsTx.Hash() != common.HexToHash("fe7a79529ed5f7c3375d06b26b186a8644e0e16c373d7a12be41c62d6042b77a") {
+ if rightvrsTx.SigHash() != common.HexToHash("fe7a79529ed5f7c3375d06b26b186a8644e0e16c373d7a12be41c62d6042b77a") {
t.Errorf("RightVRS transaction hash mismatch, got %x", rightvrsTx.Hash())
}
}
diff --git a/core/vm/errors.go b/core/vm/errors.go
index 799eb6797..75b9c0f10 100644
--- a/core/vm/errors.go
+++ b/core/vm/errors.go
@@ -1,21 +1,14 @@
package vm
import (
+ "errors"
"fmt"
"github.com/ethereum/go-ethereum/params"
)
-type OutOfGasError struct{}
-
-func (self OutOfGasError) Error() string {
- return "Out Of Gas"
-}
-
-func IsOOGErr(err error) bool {
- _, ok := err.(OutOfGasError)
- return ok
-}
+var OutOfGasError = errors.New("Out of gas")
+var DepthError = fmt.Errorf("Max call depth exceeded (%d)", params.CallCreateDepth)
type StackError struct {
req, has int
@@ -33,14 +26,3 @@ func IsStack(err error) bool {
_, ok := err.(StackError)
return ok
}
-
-type DepthError struct{}
-
-func (self DepthError) Error() string {
- return fmt.Sprintf("Max call depth exceeded (%d)", params.CallCreateDepth)
-}
-
-func IsDepthErr(err error) bool {
- _, ok := err.(DepthError)
- return ok
-}
diff --git a/core/vm/vm.go b/core/vm/vm.go
index ba803683b..e390fb89c 100644
--- a/core/vm/vm.go
+++ b/core/vm/vm.go
@@ -116,7 +116,7 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) {
context.UseGas(context.Gas)
- return context.Return(nil), OutOfGasError{}
+ return context.Return(nil), OutOfGasError
}
// Resize the memory calculated previously
mem.Resize(newMemSize.Uint64())
@@ -789,7 +789,7 @@ func (self *Vm) RunPrecompiled(p *PrecompiledAccount, input []byte, context *Con
return context.Return(ret), nil
} else {
- return nil, OutOfGasError{}
+ return nil, OutOfGasError
}
}
diff --git a/rpc/api/eth.go b/rpc/api/eth.go
index db0b4b024..6d759a087 100644
--- a/rpc/api/eth.go
+++ b/rpc/api/eth.go
@@ -77,6 +77,7 @@ var (
"eth_submitWork": (*ethApi).SubmitWork,
"eth_resend": (*ethApi).Resend,
"eth_pendingTransactions": (*ethApi).PendingTransactions,
+ "eth_getTransactionReceipt": (*ethApi).GetTransactionReceipt,
}
)
@@ -596,3 +597,28 @@ func (self *ethApi) PendingTransactions(req *shared.Request) (interface{}, error
return ltxs, nil
}
+
+func (self *ethApi) GetTransactionReceipt(req *shared.Request) (interface{}, error) {
+ args := new(HashArgs)
+ if err := self.codec.Decode(req.Params, &args); err != nil {
+ return nil, shared.NewDecodeParamError(err.Error())
+ }
+
+ txhash := common.BytesToHash(common.FromHex(args.Hash))
+ tx, bhash, bnum, txi := self.xeth.EthTransactionByHash(args.Hash)
+ rec := self.xeth.GetTxReceipt(txhash)
+ // We could have an error of "not found". Should disambiguate
+ // if err != nil {
+ // return err, nil
+ // }
+ if rec != nil && tx != nil {
+ v := NewReceiptRes(rec)
+ v.BlockHash = newHexData(bhash)
+ v.BlockNumber = newHexNum(bnum)
+ v.GasUsed = newHexNum(tx.Gas().Bytes())
+ v.TransactionIndex = newHexNum(txi)
+ return v, nil
+ }
+
+ return nil, nil
+}
diff --git a/rpc/api/parsing.go b/rpc/api/parsing.go
index 632462c31..4209ea7e3 100644
--- a/rpc/api/parsing.go
+++ b/rpc/api/parsing.go
@@ -1,6 +1,7 @@
package api
import (
+ "bytes"
"encoding/binary"
"encoding/hex"
"encoding/json"
@@ -402,6 +403,38 @@ func NewUncleRes(h *types.Header) *UncleRes {
// WorkProved string `json:"workProved"`
// }
+type ReceiptRes struct {
+ TransactionHash *hexdata `json:transactionHash`
+ TransactionIndex *hexnum `json:transactionIndex`
+ BlockNumber *hexnum `json:blockNumber`
+ BlockHash *hexdata `json:blockHash`
+ CumulativeGasUsed *hexnum `json:cumulativeGasUsed`
+ GasUsed *hexnum `json:gasUsed`
+ ContractAddress *hexdata `json:contractAddress`
+ Logs *[]interface{} `json:logs`
+}
+
+func NewReceiptRes(rec *types.Receipt) *ReceiptRes {
+ if rec == nil {
+ return nil
+ }
+
+ var v = new(ReceiptRes)
+ v.TransactionHash = newHexData(rec.TxHash)
+ // v.TransactionIndex = newHexNum(input)
+ // v.BlockNumber = newHexNum(input)
+ // v.BlockHash = newHexData(input)
+ v.CumulativeGasUsed = newHexNum(rec.CumulativeGasUsed)
+ // v.GasUsed = newHexNum(input)
+ // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
+ if bytes.Compare(rec.ContractAddress.Bytes(), bytes.Repeat([]byte{0}, 20)) != 0 {
+ v.ContractAddress = newHexData(rec.ContractAddress)
+ }
+ // v.Logs = rec.Logs()
+
+ return v
+}
+
func numString(raw interface{}) (*big.Int, error) {
var number *big.Int
// Parse as integer
diff --git a/rpc/api/utils.go b/rpc/api/utils.go
index e6a01d3d6..54ca28774 100644
--- a/rpc/api/utils.go
+++ b/rpc/api/utils.go
@@ -86,6 +86,7 @@ var (
"submitWork",
"pendingTransactions",
"resend",
+ "getTransactionReceipt",
},
"miner": []string{
"hashrate",
diff --git a/tests/init.go b/tests/init.go
index a78a2f54b..832759f7e 100644
--- a/tests/init.go
+++ b/tests/init.go
@@ -22,11 +22,6 @@ var (
BlockSkipTests = []string{
"SimpleTx3",
- // these panic in block_processor.go:84 , see https://github.com/ethereum/go-ethereum/issues/1384
- "TRANSCT_rvalue_TooShort",
- "TRANSCT_rvalue_TooLarge",
- "TRANSCT_svalue_TooLarge",
-
// TODO: check why these fail
"BLOCK__RandomByteAtTheEnd",
"TRANSCT__RandomByteAtTheEnd",
diff --git a/xeth/xeth.go b/xeth/xeth.go
index 1cec82e5e..4bd18a2f6 100644
--- a/xeth/xeth.go
+++ b/xeth/xeth.go
@@ -969,7 +969,6 @@ func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceS
if contractCreation {
addr := crypto.CreateAddress(from, nonce)
glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr)
- return addr.Hex(), nil
} else {
glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To())
}
@@ -978,7 +977,7 @@ func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceS
}
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) (*types.Transaction, error) {
- hash := tx.Hash()
+ hash := tx.SigHash()
sig, err := self.doSign(from, hash, didUnlock)
if err != nil {
return tx, err