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

The optimization of merging Ethereum #96

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package eth
import (
"context"
"errors"
"github.com/AlayaNetwork/Alaya-Go/core/rawdb"
"math/big"

"github.com/AlayaNetwork/Alaya-Go/core/snapshotdb"
Expand Down Expand Up @@ -180,6 +181,11 @@ func (b *EthAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction
return b.eth.txPool.Get(hash)
}

func (b *EthAPIBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
tx, blockHash, blockNumber, index := rawdb.ReadTransaction(b.eth.ChainDb(), txHash)
return tx, blockHash, blockNumber, index, nil
}

func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
return b.eth.txPool.Nonce(addr), nil
}
Expand Down
13 changes: 7 additions & 6 deletions ethclient/ethclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,13 @@ func (ec *Client) TransactionCount(ctx context.Context, blockHash common.Hash) (
func (ec *Client) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) {
var json *rpcTransaction
err := ec.c.CallContext(ctx, &json, "platon_getTransactionByBlockHashAndIndex", blockHash, hexutil.Uint64(index))
if err == nil {
if json == nil {
return nil, platon.NotFound
} else if _, r, _ := json.tx.RawSignatureValues(); r == nil {
return nil, fmt.Errorf("server returned transaction without signature")
}
if err != nil {
return nil, err
}
if json == nil {
return nil, platon.NotFound
} else if _, r, _ := json.tx.RawSignatureValues(); r == nil {
return nil, fmt.Errorf("server returned transaction without signature")
}
if json.From != nil && json.BlockHash != nil {
setSenderFromServer(json.tx, *json.From, *json.BlockHash)
Expand Down
22 changes: 14 additions & 8 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1145,25 +1145,31 @@ func (s *PublicTransactionPoolAPI) GetPoolNonce(ctx context.Context, address com
}

// GetTransactionByHash returns the transaction for the given hash
func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) *RPCTransaction {
func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) {
// Try to return an already finalized transaction
if tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash); tx != nil {
return newRPCTransaction(tx, blockHash, blockNumber, index)
tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash)
if err != nil {
return nil, err
}
if tx != nil {
return newRPCTransaction(tx, blockHash, blockNumber, index), nil
}
// No finalized transaction, try to retrieve it from the pool
if tx := s.b.GetPoolTransaction(hash); tx != nil {
return newRPCPendingTransaction(tx)
return newRPCPendingTransaction(tx), nil
}
// Transaction unknown, return as such
return nil
return nil, nil
}

// GetRawTransactionByHash returns the bytes of the transaction for the given hash.
func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
var tx *types.Transaction

// Retrieve a finalized transaction, or a pooled otherwise
if tx, _, _, _ = rawdb.ReadTransaction(s.b.ChainDb(), hash); tx == nil {
tx, _, _, _, err := s.b.GetTransaction(ctx, hash)
if err != nil {
return nil, err
}
if tx == nil {
if tx = s.b.GetPoolTransaction(hash); tx == nil {
// Transaction not found anywhere, abort
return nil, nil
Expand Down
1 change: 1 addition & 0 deletions internal/ethapi/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type Backend interface {

// TxPool API
SendTx(ctx context.Context, signedTx *types.Transaction) error
GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error)
GetPoolTransactions() (types.Transactions, error)
GetPoolTransaction(txHash common.Hash) *types.Transaction
GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
Expand Down
4 changes: 4 additions & 0 deletions les/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ func (b *LesApiBackend) GetPoolTransaction(txHash common.Hash) *types.Transactio
return b.eth.txPool.GetTransaction(txHash)
}

func (b *LesApiBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
return nil, common.ZeroHash, 0, 0, nil
}

func (b *LesApiBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
return b.eth.txPool.GetNonce(ctx, addr)
}
Expand Down
30 changes: 16 additions & 14 deletions rlp/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,17 @@ type Decoder interface {
// type, Decode will return an error. Decode also supports *big.Int.
// There is no size limit for big integers.
//
// To decode into a boolean, the input must contain an unsigned integer
// of value zero (false) or one (true).
//
// To decode into an interface value, Decode stores one of these
// in the value:
//
// []interface{}, for RLP lists
// []byte, for RLP strings
//
// Non-empty interface types are not supported, nor are booleans,
// signed integers, floating point numbers, maps, channels and
// functions.
// Non-empty interface types are not supported, nor are signed integers,
// floating point numbers, maps, channels and functions.
//
// Note that Decode does not set an input limit for all readers
// and may be vulnerable to panics cause by huge value sizes. If
Expand Down Expand Up @@ -306,9 +308,9 @@ func makeListDecoder(typ reflect.Type, tag tags) (decoder, error) {
}
return decodeByteSlice, nil
}
etypeinfo, err := cachedTypeInfo1(etype, tags{})
if err != nil {
return nil, err
etypeinfo := cachedTypeInfo1(etype, tags{})
if etypeinfo.decoderErr != nil {
return nil, etypeinfo.decoderErr
}
var dec decoder
switch {
Expand Down Expand Up @@ -467,9 +469,9 @@ func makeStructDecoder(typ reflect.Type) (decoder, error) {
// the pointer's element type.
func makePtrDecoder(typ reflect.Type) (decoder, error) {
etype := typ.Elem()
etypeinfo, err := cachedTypeInfo1(etype, tags{})
if err != nil {
return nil, err
etypeinfo := cachedTypeInfo1(etype, tags{})
if etypeinfo.decoderErr != nil {
return nil, etypeinfo.decoderErr
}
dec := func(s *Stream, val reflect.Value) (err error) {
newval := val
Expand All @@ -491,9 +493,9 @@ func makePtrDecoder(typ reflect.Type) (decoder, error) {
// This decoder is used for pointer-typed struct fields with struct tag "nil".
func makeOptionalPtrDecoder(typ reflect.Type) (decoder, error) {
etype := typ.Elem()
etypeinfo, err := cachedTypeInfo1(etype, tags{})
if err != nil {
return nil, err
etypeinfo := cachedTypeInfo1(etype, tags{})
if etypeinfo.decoderErr != nil {
return nil, etypeinfo.decoderErr
}
dec := func(s *Stream, val reflect.Value) (err error) {
kind, size, err := s.Kind()
Expand Down Expand Up @@ -814,12 +816,12 @@ func (s *Stream) Decode(val interface{}) error {
if rval.IsNil() {
return errDecodeIntoNil
}
info, err := cachedTypeInfo(rtyp.Elem(), tags{})
decoder, err := cachedDecoder(rtyp.Elem())
if err != nil {
return err
}

err = info.decoder(s, rval.Elem())
err = decoder(s, rval.Elem())
if decErr, ok := err.(*decodeError); ok && len(decErr.ctx) > 0 {
// add decode target type to error so context has more meaning
decErr.ctx = append(decErr.ctx, fmt.Sprint("(", rtyp.Elem(), ")"))
Expand Down
32 changes: 32 additions & 0 deletions rlp/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,12 @@ type tailUint struct {
Tail []uint `rlp:"tail"`
}

type tailPrivateFields struct {
A uint
Tail []uint `rlp:"tail"`
x, y bool
}

var (
veryBigInt = big.NewInt(0).Add(
big.NewInt(0).Lsh(big.NewInt(0xFFFFFFFFFFFFFF), 16),
Expand Down Expand Up @@ -540,6 +546,11 @@ var decodeTests = []decodeTest{
ptr: new(tailRaw),
value: tailRaw{A: 1, Tail: []RawValue{}},
},
{
input: "C3010203",
ptr: new(tailPrivateFields),
value: tailPrivateFields{A: 1, Tail: []uint{2, 3}},
},

// struct tag "-"
{
Expand Down Expand Up @@ -721,6 +732,27 @@ func TestDecoderInByteSlice(t *testing.T) {
}
}

type unencodableDecoder func()

func (f *unencodableDecoder) DecodeRLP(s *Stream) error {
if _, err := s.List(); err != nil {
return err
}
if err := s.ListEnd(); err != nil {
return err
}
*f = func() {}
return nil
}

func TestDecoderFunc(t *testing.T) {
var x func()
if err := DecodeBytes([]byte{0xC0}, (*unencodableDecoder)(&x)); err != nil {
t.Fatal(err)
}
x()
}

func ExampleDecode() {
input, _ := hex.DecodeString("C90A1486666F6F626172")

Expand Down
26 changes: 13 additions & 13 deletions rlp/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ type Encoder interface {
//
// An interface value encodes as the value contained in the interface.
//
// Boolean values are not supported, nor are signed integers, floating
// point numbers, maps, channels and functions.
// Signed integers are not supported, nor are floating point numbers, maps,
// channels and functions.
func Encode(w io.Writer, val interface{}) error {
if outer, ok := w.(*encbuf); ok {
// Encode was called by some type's EncodeRLP.
Expand Down Expand Up @@ -182,11 +182,11 @@ func (w *encbuf) Write(b []byte) (int, error) {

func (w *encbuf) encode(val interface{}) error {
rval := reflect.ValueOf(val)
ti, err := cachedTypeInfo(rval.Type(), tags{})
writer, err := cachedWriter(rval.Type())
if err != nil {
return err
}
return ti.writer(rval, w)
return writer(rval, w)
}

func (w *encbuf) encodeStringHeader(size int) {
Expand Down Expand Up @@ -499,17 +499,17 @@ func writeInterface(val reflect.Value, w *encbuf) error {
return nil
}
eval := val.Elem()
ti, err := cachedTypeInfo(eval.Type(), tags{})
writer, err := cachedWriter(eval.Type())
if err != nil {
return err
}
return ti.writer(eval, w)
return writer(eval, w)
}

func makeSliceWriter(typ reflect.Type, ts tags) (writer, error) {
etypeinfo, err := cachedTypeInfo1(typ.Elem(), tags{})
if err != nil {
return nil, err
etypeinfo := cachedTypeInfo1(typ.Elem(), tags{})
if etypeinfo.writerErr != nil {
return nil, etypeinfo.writerErr
}
writer := func(val reflect.Value, w *encbuf) error {
if !ts.tail {
Expand Down Expand Up @@ -545,9 +545,9 @@ func makeStructWriter(typ reflect.Type) (writer, error) {
}

func makePtrWriter(typ reflect.Type) (writer, error) {
etypeinfo, err := cachedTypeInfo1(typ.Elem(), tags{})
if err != nil {
return nil, err
etypeinfo := cachedTypeInfo1(typ.Elem(), tags{})
if etypeinfo.writerErr != nil {
return nil, etypeinfo.writerErr
}

// determine nil pointer handler
Expand Down Expand Up @@ -579,7 +579,7 @@ func makePtrWriter(typ reflect.Type) (writer, error) {
}
return etypeinfo.writer(val.Elem(), w)
}
return writer, err
return writer, nil
}

// putint writes i to the beginning of b in big endian byte
Expand Down
9 changes: 9 additions & 0 deletions rlp/encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ func (e byteEncoder) EncodeRLP(w io.Writer) error {
return nil
}

type undecodableEncoder func()

func (f undecodableEncoder) EncodeRLP(w io.Writer) error {
_, err := w.Write(EmptyList)
return err
}

type encodableReader struct {
A, B uint
}
Expand Down Expand Up @@ -244,6 +251,8 @@ var encTests = []encTest{
{val: (*testEncoder)(nil), output: "00000000"},
{val: &testEncoder{}, output: "00010001000100010001"},
{val: &testEncoder{errors.New("test error")}, error: "test error"},
// verify that the Encoder interface works for unsupported types like func().
{val: undecodableEncoder(func() {}), output: "C0"},
// verify that pointer method testEncoder.EncodeRLP is called for
// addressable non-pointer values.
{val: &struct{ TE testEncoder }{testEncoder{}}, output: "CA00010001000100010001"},
Expand Down
Loading