forked from cerc-io/plugeth
Merge branch 'conversion' of github.com-obscure:ethereum/go-ethereum into conversion
This commit is contained in:
commit
4d0ae8b0cb
@ -221,13 +221,10 @@ func (js *jsre) exportChain(call otto.FunctionCall) otto.Value {
|
|||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return otto.FalseValue()
|
return otto.FalseValue()
|
||||||
}
|
}
|
||||||
|
if err := utils.ExportChain(js.ethereum.ChainManager(), fn); err != nil {
|
||||||
data := js.ethereum.ChainManager().Export()
|
|
||||||
if err := common.WriteFile(fn, data); err != nil {
|
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return otto.FalseValue()
|
return otto.FalseValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
return otto.TrueValue()
|
return otto.TrueValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,14 +23,15 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
@ -152,29 +153,34 @@ func ImportChain(chainmgr *core.ChainManager, fn string) error {
|
|||||||
}
|
}
|
||||||
defer fh.Close()
|
defer fh.Close()
|
||||||
|
|
||||||
var blocks types.Blocks
|
|
||||||
if err := rlp.Decode(fh, &blocks); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
chainmgr.Reset()
|
chainmgr.Reset()
|
||||||
if err := chainmgr.InsertChain(blocks); err != nil {
|
stream := rlp.NewStream(fh)
|
||||||
return err
|
var i int
|
||||||
|
for ; ; i++ {
|
||||||
|
var b types.Block
|
||||||
|
if err := stream.Decode(&b); err == io.EOF {
|
||||||
|
break
|
||||||
|
} else if err != nil {
|
||||||
|
return fmt.Errorf("at block %d: %v", i, err)
|
||||||
|
}
|
||||||
|
if err := chainmgr.InsertChain(types.Blocks{&b}); err != nil {
|
||||||
|
return fmt.Errorf("invalid block %d: %v", i, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fmt.Printf("imported %d blocks\n", len(blocks))
|
fmt.Printf("imported %d blocks\n", i)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExportChain(chainmgr *core.ChainManager, fn string) error {
|
func ExportChain(chainmgr *core.ChainManager, fn string) error {
|
||||||
fmt.Printf("exporting blockchain '%s'\n", fn)
|
fmt.Printf("exporting blockchain '%s'\n", fn)
|
||||||
|
fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
|
||||||
data := chainmgr.Export()
|
if err != nil {
|
||||||
|
return err
|
||||||
if err := common.WriteFile(fn, data); err != nil {
|
}
|
||||||
|
defer fh.Close()
|
||||||
|
if err := chainmgr.Export(fh); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Printf("exported blockchain\n")
|
fmt.Printf("exported blockchain\n")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/pow/ezp"
|
"github.com/ethereum/go-ethereum/pow/ezp"
|
||||||
@ -19,7 +20,7 @@ func proc() (*BlockProcessor, *ChainManager) {
|
|||||||
|
|
||||||
func TestNumber(t *testing.T) {
|
func TestNumber(t *testing.T) {
|
||||||
bp, chain := proc()
|
bp, chain := proc()
|
||||||
block1 := chain.NewBlock(nil)
|
block1 := chain.NewBlock(common.Address{})
|
||||||
block1.Header().Number = big.NewInt(3)
|
block1.Header().Number = big.NewInt(3)
|
||||||
|
|
||||||
err := bp.ValidateHeader(block1.Header(), chain.Genesis().Header())
|
err := bp.ValidateHeader(block1.Header(), chain.Genesis().Header())
|
||||||
@ -27,7 +28,7 @@ func TestNumber(t *testing.T) {
|
|||||||
t.Errorf("expected block number error")
|
t.Errorf("expected block number error")
|
||||||
}
|
}
|
||||||
|
|
||||||
block1 = chain.NewBlock(nil)
|
block1 = chain.NewBlock(common.Address{})
|
||||||
err = bp.ValidateHeader(block1.Header(), chain.Genesis().Header())
|
err = bp.ValidateHeader(block1.Header(), chain.Genesis().Header())
|
||||||
if err == BlockNumberErr {
|
if err == BlockNumberErr {
|
||||||
t.Errorf("didn't expect block number error")
|
t.Errorf("didn't expect block number error")
|
||||||
|
@ -3,6 +3,7 @@ package core
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -254,22 +255,20 @@ func (bc *ChainManager) ResetWithGenesisBlock(gb *types.Block) {
|
|||||||
bc.currentBlock = bc.genesisBlock
|
bc.currentBlock = bc.genesisBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ChainManager) Export() []byte {
|
// Export writes the active chain to the given writer.
|
||||||
|
func (self *ChainManager) Export(w io.Writer) error {
|
||||||
self.mu.RLock()
|
self.mu.RLock()
|
||||||
defer self.mu.RUnlock()
|
defer self.mu.RUnlock()
|
||||||
|
|
||||||
chainlogger.Infof("exporting %v blocks...\n", self.currentBlock.Header().Number)
|
chainlogger.Infof("exporting %v blocks...\n", self.currentBlock.Header().Number)
|
||||||
|
|
||||||
blocks := make([]*types.Block, int(self.currentBlock.NumberU64())+1)
|
|
||||||
for block := self.currentBlock; block != nil; block = self.GetBlock(block.Header().ParentHash) {
|
for block := self.currentBlock; block != nil; block = self.GetBlock(block.Header().ParentHash) {
|
||||||
blocks[block.NumberU64()] = block
|
if err := block.EncodeRLP(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
return common.Encode(blocks)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *ChainManager) insert(block *types.Block) {
|
func (bc *ChainManager) insert(block *types.Block) {
|
||||||
//encodedBlock := common.Encode(block)
|
|
||||||
bc.blockDb.Put([]byte("LastBlock"), block.Hash().Bytes())
|
bc.blockDb.Put([]byte("LastBlock"), block.Hash().Bytes())
|
||||||
bc.currentBlock = block
|
bc.currentBlock = block
|
||||||
bc.lastBlockHash = block.Hash()
|
bc.lastBlockHash = block.Hash()
|
||||||
@ -279,10 +278,9 @@ func (bc *ChainManager) insert(block *types.Block) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bc *ChainManager) write(block *types.Block) {
|
func (bc *ChainManager) write(block *types.Block) {
|
||||||
encodedBlock := common.Encode(block.RlpDataForStorage())
|
enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block))
|
||||||
|
|
||||||
key := append(blockHashPre, block.Hash().Bytes()...)
|
key := append(blockHashPre, block.Hash().Bytes()...)
|
||||||
bc.blockDb.Put(key, encodedBlock)
|
bc.blockDb.Put(key, enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
@ -324,13 +322,12 @@ func (self *ChainManager) GetBlock(hash common.Hash) *types.Block {
|
|||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var block types.Block
|
var block types.StorageBlock
|
||||||
if err := rlp.Decode(bytes.NewReader(data), &block); err != nil {
|
if err := rlp.Decode(bytes.NewReader(data), &block); err != nil {
|
||||||
fmt.Println(err)
|
chainlogger.Errorf("invalid block RLP for hash %x: %v", hash, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
return (*types.Block)(&block)
|
||||||
return &block
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
|
func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
@ -35,7 +34,7 @@ func testFork(t *testing.T, bman *BlockProcessor, i, N int, f func(td1, td2 *big
|
|||||||
// asert the bmans have the same block at i
|
// asert the bmans have the same block at i
|
||||||
bi1 := bman.bc.GetBlockByNumber(uint64(i)).Hash()
|
bi1 := bman.bc.GetBlockByNumber(uint64(i)).Hash()
|
||||||
bi2 := bman2.bc.GetBlockByNumber(uint64(i)).Hash()
|
bi2 := bman2.bc.GetBlockByNumber(uint64(i)).Hash()
|
||||||
if bytes.Compare(bi1, bi2) != 0 {
|
if bi1 != bi2 {
|
||||||
t.Fatal("chains do not have the same hash at height", i)
|
t.Fatal("chains do not have the same hash at height", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,11 +269,11 @@ func TestChainInsertions(t *testing.T) {
|
|||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytes.Equal(chain2[len(chain2)-1].Hash(), chainMan.CurrentBlock().Hash()) {
|
if chain2[len(chain2)-1].Hash() != chainMan.CurrentBlock().Hash() {
|
||||||
t.Error("chain2 is canonical and shouldn't be")
|
t.Error("chain2 is canonical and shouldn't be")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(chain1[len(chain1)-1].Hash(), chainMan.CurrentBlock().Hash()) {
|
if chain1[len(chain1)-1].Hash() != chainMan.CurrentBlock().Hash() {
|
||||||
t.Error("chain1 isn't canonical and should be")
|
t.Error("chain1 isn't canonical and should be")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,7 +319,7 @@ func TestChainMultipleInsertions(t *testing.T) {
|
|||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(chains[longest][len(chains[longest])-1].Hash(), chainMan.CurrentBlock().Hash()) {
|
if chains[longest][len(chains[longest])-1].Hash() != chainMan.CurrentBlock().Hash() {
|
||||||
t.Error("Invalid canonical chain")
|
t.Error("Invalid canonical chain")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,9 +18,6 @@ import (
|
|||||||
var ZeroHash256 = make([]byte, 32)
|
var ZeroHash256 = make([]byte, 32)
|
||||||
var ZeroHash160 = make([]byte, 20)
|
var ZeroHash160 = make([]byte, 20)
|
||||||
var ZeroHash512 = make([]byte, 64)
|
var ZeroHash512 = make([]byte, 64)
|
||||||
var EmptyShaList = crypto.Sha3(common.Encode([]interface{}{}))
|
|
||||||
var EmptyListRoot = crypto.Sha3(common.Encode(""))
|
|
||||||
|
|
||||||
var GenesisDiff = big.NewInt(131072)
|
var GenesisDiff = big.NewInt(131072)
|
||||||
var GenesisGasLimit = big.NewInt(3141592)
|
var GenesisGasLimit = big.NewInt(3141592)
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ func NewTxPool(eventMux *event.TypeMux) *TxPool {
|
|||||||
func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
|
func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
|
||||||
// Validate sender
|
// Validate sender
|
||||||
if _, err := tx.From(); err != nil {
|
if _, err := tx.From(); err != nil {
|
||||||
return err
|
return ErrInvalidSender
|
||||||
}
|
}
|
||||||
// Validate curve param
|
// Validate curve param
|
||||||
v, _, _ := tx.Curve()
|
v, _, _ := tx.Curve()
|
||||||
|
@ -4,10 +4,10 @@ import (
|
|||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
)
|
)
|
||||||
@ -21,11 +21,11 @@ func SQ() stateQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self stateQuery) GetAccount(addr []byte) *state.StateObject {
|
func (self stateQuery) GetAccount(addr []byte) *state.StateObject {
|
||||||
return state.NewStateObject(addr, self.db)
|
return state.NewStateObject(common.BytesToAddress(addr), self.db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func transaction() *types.Transaction {
|
func transaction() *types.Transaction {
|
||||||
return types.NewTransactionMessage(make([]byte, 20), common.Big0, common.Big0, common.Big0, nil)
|
return types.NewTransactionMessage(common.Address{}, common.Big0, common.Big0, common.Big0, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setup() (*TxPool, *ecdsa.PrivateKey) {
|
func setup() (*TxPool, *ecdsa.PrivateKey) {
|
||||||
@ -88,10 +88,8 @@ func TestRemoveInvalid(t *testing.T) {
|
|||||||
|
|
||||||
func TestInvalidSender(t *testing.T) {
|
func TestInvalidSender(t *testing.T) {
|
||||||
pool, _ := setup()
|
pool, _ := setup()
|
||||||
tx := new(types.Transaction)
|
err := pool.ValidateTransaction(new(types.Transaction))
|
||||||
tx.V = 28
|
|
||||||
err := pool.ValidateTransaction(tx)
|
|
||||||
if err != ErrInvalidSender {
|
if err != ErrInvalidSender {
|
||||||
t.Error("expected %v, got %v", ErrInvalidSender, err)
|
t.Errorf("expected %v, got %v", ErrInvalidSender, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,13 @@ package types
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -45,6 +46,14 @@ type Header struct {
|
|||||||
Nonce [8]byte
|
Nonce [8]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Header) Hash() common.Hash {
|
||||||
|
return rlpHash(self.rlpData(true))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Header) HashNoNonce() common.Hash {
|
||||||
|
return rlpHash(self.rlpData(false))
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Header) rlpData(withNonce bool) []interface{} {
|
func (self *Header) rlpData(withNonce bool) []interface{} {
|
||||||
fields := []interface{}{
|
fields := []interface{}{
|
||||||
self.ParentHash,
|
self.ParentHash,
|
||||||
@ -64,7 +73,6 @@ func (self *Header) rlpData(withNonce bool) []interface{} {
|
|||||||
if withNonce {
|
if withNonce {
|
||||||
fields = append(fields, self.MixDigest, self.Nonce)
|
fields = append(fields, self.MixDigest, self.Nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,12 +80,11 @@ func (self *Header) RlpData() interface{} {
|
|||||||
return self.rlpData(true)
|
return self.rlpData(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Header) Hash() common.Hash {
|
func rlpHash(x interface{}) (h common.Hash) {
|
||||||
return common.BytesToHash(crypto.Sha3(common.Encode(self.rlpData(true))))
|
hw := sha3.NewKeccak256()
|
||||||
}
|
rlp.Encode(hw, x)
|
||||||
|
hw.Sum(h[:0])
|
||||||
func (self *Header) HashNoNonce() common.Hash {
|
return h
|
||||||
return common.BytesToHash(crypto.Sha3(common.Encode(self.rlpData(false))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Block struct {
|
type Block struct {
|
||||||
@ -95,6 +102,26 @@ type Block struct {
|
|||||||
Reward *big.Int
|
Reward *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StorageBlock defines the RLP encoding of a Block stored in the
|
||||||
|
// state database. The StorageBlock encoding contains fields that
|
||||||
|
// would otherwise need to be recomputed.
|
||||||
|
type StorageBlock Block
|
||||||
|
|
||||||
|
// "external" block encoding. used for eth protocol, etc.
|
||||||
|
type extblock struct {
|
||||||
|
Header *Header
|
||||||
|
Txs []*Transaction
|
||||||
|
Uncles []*Header
|
||||||
|
}
|
||||||
|
|
||||||
|
// "storage" block encoding. used for database.
|
||||||
|
type storageblock struct {
|
||||||
|
Header *Header
|
||||||
|
Txs []*Transaction
|
||||||
|
Uncles []*Header
|
||||||
|
TD *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
func NewBlock(parentHash common.Hash, coinbase common.Address, root common.Hash, difficulty *big.Int, nonce uint64, extra string) *Block {
|
func NewBlock(parentHash common.Hash, coinbase common.Address, root common.Hash, difficulty *big.Int, nonce uint64, extra string) *Block {
|
||||||
header := &Header{
|
header := &Header{
|
||||||
Root: root,
|
Root: root,
|
||||||
@ -107,9 +134,7 @@ func NewBlock(parentHash common.Hash, coinbase common.Address, root common.Hash,
|
|||||||
GasLimit: new(big.Int),
|
GasLimit: new(big.Int),
|
||||||
}
|
}
|
||||||
header.SetNonce(nonce)
|
header.SetNonce(nonce)
|
||||||
|
|
||||||
block := &Block{header: header, Reward: new(big.Int)}
|
block := &Block{header: header, Reward: new(big.Int)}
|
||||||
|
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,22 +147,40 @@ func NewBlockWithHeader(header *Header) *Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Block) DecodeRLP(s *rlp.Stream) error {
|
func (self *Block) DecodeRLP(s *rlp.Stream) error {
|
||||||
var extblock struct {
|
var eb extblock
|
||||||
Header *Header
|
if err := s.Decode(&eb); err != nil {
|
||||||
Txs []*Transaction
|
|
||||||
Uncles []*Header
|
|
||||||
TD *big.Int // optional
|
|
||||||
}
|
|
||||||
if err := s.Decode(&extblock); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
self.header = extblock.Header
|
self.header, self.uncles, self.transactions = eb.Header, eb.Uncles, eb.Txs
|
||||||
self.uncles = extblock.Uncles
|
|
||||||
self.transactions = extblock.Txs
|
|
||||||
self.Td = extblock.TD
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self Block) EncodeRLP(w io.Writer) error {
|
||||||
|
return rlp.Encode(w, extblock{
|
||||||
|
Header: self.header,
|
||||||
|
Txs: self.transactions,
|
||||||
|
Uncles: self.uncles,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *StorageBlock) DecodeRLP(s *rlp.Stream) error {
|
||||||
|
var sb storageblock
|
||||||
|
if err := s.Decode(&sb); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
self.header, self.uncles, self.transactions, self.Td = sb.Header, sb.Uncles, sb.Txs, sb.TD
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self StorageBlock) EncodeRLP(w io.Writer) error {
|
||||||
|
return rlp.Encode(w, storageblock{
|
||||||
|
Header: self.header,
|
||||||
|
Txs: self.transactions,
|
||||||
|
Uncles: self.uncles,
|
||||||
|
TD: self.Td,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Block) Header() *Header {
|
func (self *Block) Header() *Header {
|
||||||
return self.header
|
return self.header
|
||||||
}
|
}
|
||||||
@ -148,7 +191,7 @@ func (self *Block) Uncles() []*Header {
|
|||||||
|
|
||||||
func (self *Block) SetUncles(uncleHeaders []*Header) {
|
func (self *Block) SetUncles(uncleHeaders []*Header) {
|
||||||
self.uncles = uncleHeaders
|
self.uncles = uncleHeaders
|
||||||
self.header.UncleHash = common.BytesToHash(crypto.Sha3(common.Encode(uncleHeaders)))
|
self.header.UncleHash = rlpHash(uncleHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Block) Transactions() Transactions {
|
func (self *Block) Transactions() Transactions {
|
||||||
@ -213,7 +256,6 @@ func (self *Block) GasLimit() *big.Int { return self.header.GasLimit }
|
|||||||
func (self *Block) GasUsed() *big.Int { return self.header.GasUsed }
|
func (self *Block) GasUsed() *big.Int { return self.header.GasUsed }
|
||||||
func (self *Block) Root() common.Hash { return self.header.Root }
|
func (self *Block) Root() common.Hash { return self.header.Root }
|
||||||
func (self *Block) SetRoot(root common.Hash) { self.header.Root = root }
|
func (self *Block) SetRoot(root common.Hash) { self.header.Root = root }
|
||||||
func (self *Block) Size() common.StorageSize { return common.StorageSize(len(common.Encode(self))) }
|
|
||||||
func (self *Block) GetTransaction(i int) *Transaction {
|
func (self *Block) GetTransaction(i int) *Transaction {
|
||||||
if len(self.transactions) > i {
|
if len(self.transactions) > i {
|
||||||
return self.transactions[i]
|
return self.transactions[i]
|
||||||
@ -227,6 +269,19 @@ func (self *Block) GetUncle(i int) *Header {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Block) Size() common.StorageSize {
|
||||||
|
c := writeCounter(0)
|
||||||
|
rlp.Encode(&c, self)
|
||||||
|
return common.StorageSize(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
type writeCounter common.StorageSize
|
||||||
|
|
||||||
|
func (c *writeCounter) Write(b []byte) (int, error) {
|
||||||
|
*c += writeCounter(len(b))
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Implement pow.Block
|
// Implement pow.Block
|
||||||
func (self *Block) Difficulty() *big.Int { return self.header.Difficulty }
|
func (self *Block) Difficulty() *big.Int { return self.header.Difficulty }
|
||||||
func (self *Block) HashNoNonce() common.Hash { return self.header.HashNoNonce() }
|
func (self *Block) HashNoNonce() common.Hash { return self.header.HashNoNonce() }
|
||||||
|
@ -1,19 +1,60 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// XXX Tests doesn't really do anything. This tests exists while working on the fixed size conversions
|
// from bcValidBlockTest.json, "SimpleTx"
|
||||||
func TestConversion(t *testing.T) {
|
func TestBlockEncoding(t *testing.T) {
|
||||||
var (
|
blockEnc := common.FromHex("f90260f901f9a083cafc574e1f51ba9dc0568fc617a08ea2429fb384059c972f13b19fa1c8dd55a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017a05fe50b260da6308036625b850b5d6ced6d0a9f814c0688bc91ffb7b7a3a54b67a0bc37d79753ad738a6dac4921e57392f145d8887476de3f783dfa7edae9283e52b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd8825208845506eb0780a0bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff49888a13a5a8c8f2bb1c4f861f85f800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba09bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094fa08a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1c0")
|
||||||
parent common.Hash
|
|
||||||
coinbase common.Address
|
|
||||||
hash common.Hash
|
|
||||||
)
|
|
||||||
|
|
||||||
NewBlock(parent, coinbase, hash, big.NewInt(0), 0, "")
|
var block Block
|
||||||
|
if err := rlp.DecodeBytes(blockEnc, &block); err != nil {
|
||||||
|
t.Fatal("decode error: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
check := func(f string, got, want interface{}) {
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("%s mismatch: got %v, want %v", f, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
check("Difficulty", block.Difficulty(), big.NewInt(131072))
|
||||||
|
check("GasLimit", block.GasLimit(), big.NewInt(3141592))
|
||||||
|
check("GasUsed", block.GasUsed(), big.NewInt(21000))
|
||||||
|
check("Coinbase", block.Coinbase(), common.HexToAddress("8888f1f195afa192cfee860698584c030f4c9db1"))
|
||||||
|
check("MixDigest", block.MixDigest(), common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498"))
|
||||||
|
check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017"))
|
||||||
|
check("Hash", block.Hash(), common.HexToHash("0a5843ac1cb04865017cb35a57b50b07084e5fcee39b5acadade33149f4fff9e"))
|
||||||
|
check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4))
|
||||||
|
check("Time", block.Time(), int64(1426516743))
|
||||||
|
check("Size", block.Size(), common.StorageSize(len(blockEnc)))
|
||||||
|
|
||||||
|
to := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
|
||||||
|
check("Transactions", block.Transactions(), Transactions{
|
||||||
|
{
|
||||||
|
Payload: []byte{},
|
||||||
|
Amount: big.NewInt(10),
|
||||||
|
Price: big.NewInt(10),
|
||||||
|
GasLimit: big.NewInt(50000),
|
||||||
|
AccountNonce: 0,
|
||||||
|
V: 27,
|
||||||
|
R: common.FromHex("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f"),
|
||||||
|
S: common.FromHex("8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1"),
|
||||||
|
Recipient: &to,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
ourBlockEnc, err := rlp.EncodeToBytes(&block)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("encode error: ", err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(ourBlockEnc, blockEnc) {
|
||||||
|
t.Errorf("encoded block mismatch:\ngot: %x\nwant: %x", ourBlockEnc, blockEnc)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package types
|
|||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,7 +16,8 @@ func DeriveSha(list DerivableList) common.Hash {
|
|||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
trie := trie.New(nil, db)
|
trie := trie.New(nil, db)
|
||||||
for i := 0; i < list.Len(); i++ {
|
for i := 0; i < list.Len(); i++ {
|
||||||
trie.Update(common.Encode(i), list.GetRlp(i))
|
key, _ := rlp.EncodeToBytes(i)
|
||||||
|
trie.Update(key, list.GetRlp(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
return common.BytesToHash(trie.Root())
|
return common.BytesToHash(trie.Root())
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"crypto/ecdsa"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
||||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,16 +36,18 @@ func NewTransactionMessage(to common.Address, amount, gasAmount, gasPrice *big.I
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewTransactionFromBytes(data []byte) *Transaction {
|
func NewTransactionFromBytes(data []byte) *Transaction {
|
||||||
|
// TODO: remove this function if possible. callers would
|
||||||
|
// much better off decoding into transaction directly.
|
||||||
|
// it's not that hard.
|
||||||
tx := new(Transaction)
|
tx := new(Transaction)
|
||||||
rlp.Decode(bytes.NewReader(data), tx)
|
rlp.DecodeBytes(data, tx)
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) Hash() (a common.Hash) {
|
func (tx *Transaction) Hash() common.Hash {
|
||||||
h := sha3.NewKeccak256()
|
return rlpHash([]interface{}{
|
||||||
rlp.Encode(h, []interface{}{tx.AccountNonce, tx.Price, tx.GasLimit, tx.Recipient, tx.Amount, tx.Payload})
|
tx.AccountNonce, tx.Price, tx.GasLimit, tx.Recipient, tx.Amount, tx.Payload,
|
||||||
h.Sum(a[:0])
|
})
|
||||||
return a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) Data() []byte {
|
func (self *Transaction) Data() []byte {
|
||||||
@ -122,17 +122,14 @@ func (tx *Transaction) SetSignatureValues(sig []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx Transaction) EncodeRLP(w io.Writer) error {
|
func (tx *Transaction) SignECDSA(prv *ecdsa.PrivateKey) error {
|
||||||
return rlp.Encode(w, []interface{}{
|
h := tx.Hash()
|
||||||
tx.AccountNonce,
|
sig, err := crypto.Sign(h[:], prv)
|
||||||
tx.Price, tx.GasLimit,
|
if err != nil {
|
||||||
tx.Recipient,
|
return err
|
||||||
tx.Amount,
|
}
|
||||||
tx.Payload,
|
tx.SetSignatureValues(sig)
|
||||||
tx.V,
|
return nil
|
||||||
tx.R,
|
|
||||||
tx.S,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove
|
// TODO: remove
|
||||||
@ -141,11 +138,6 @@ func (tx *Transaction) RlpData() interface{} {
|
|||||||
return append(data, tx.V, new(big.Int).SetBytes(tx.R).Bytes(), new(big.Int).SetBytes(tx.S).Bytes())
|
return append(data, tx.V, new(big.Int).SetBytes(tx.R).Bytes(), new(big.Int).SetBytes(tx.S).Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove
|
|
||||||
func (tx *Transaction) RlpEncode() []byte {
|
|
||||||
return common.Encode(tx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Transaction) String() string {
|
func (tx *Transaction) String() string {
|
||||||
var from, to string
|
var from, to string
|
||||||
if f, err := tx.From(); err != nil {
|
if f, err := tx.From(); err != nil {
|
||||||
@ -158,6 +150,7 @@ func (tx *Transaction) String() string {
|
|||||||
} else {
|
} else {
|
||||||
to = fmt.Sprintf("%x", t[:])
|
to = fmt.Sprintf("%x", t[:])
|
||||||
}
|
}
|
||||||
|
enc, _ := rlp.EncodeToBytes(tx)
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
TX(%x)
|
TX(%x)
|
||||||
Contract: %v
|
Contract: %v
|
||||||
@ -185,7 +178,7 @@ func (tx *Transaction) String() string {
|
|||||||
tx.V,
|
tx.V,
|
||||||
tx.R,
|
tx.R,
|
||||||
tx.S,
|
tx.S,
|
||||||
common.Encode(tx),
|
enc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,9 +197,13 @@ func (self Transactions) RlpData() interface{} {
|
|||||||
return enc
|
return enc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Transactions) Len() int { return len(s) }
|
func (s Transactions) Len() int { return len(s) }
|
||||||
func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
func (s Transactions) GetRlp(i int) []byte { return common.Rlp(s[i]) }
|
|
||||||
|
func (s Transactions) GetRlp(i int) []byte {
|
||||||
|
enc, _ := rlp.EncodeToBytes(s[i])
|
||||||
|
return enc
|
||||||
|
}
|
||||||
|
|
||||||
type TxByNonce struct{ Transactions }
|
type TxByNonce struct{ Transactions }
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package rlp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -73,6 +74,12 @@ func Decode(r io.Reader, val interface{}) error {
|
|||||||
return NewStream(r).Decode(val)
|
return NewStream(r).Decode(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodeBytes parses RLP data from b into val.
|
||||||
|
// Please see the documentation of Decode for the decoding rules.
|
||||||
|
func DecodeBytes(b []byte, val interface{}) error {
|
||||||
|
return NewStream(bytes.NewReader(b)).Decode(val)
|
||||||
|
}
|
||||||
|
|
||||||
type decodeError struct {
|
type decodeError struct {
|
||||||
msg string
|
msg string
|
||||||
typ reflect.Type
|
typ reflect.Type
|
||||||
|
@ -386,7 +386,12 @@ func writeUint(val reflect.Value, w *encbuf) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func writeBigIntPtr(val reflect.Value, w *encbuf) error {
|
func writeBigIntPtr(val reflect.Value, w *encbuf) error {
|
||||||
return writeBigInt(val.Interface().(*big.Int), w)
|
ptr := val.Interface().(*big.Int)
|
||||||
|
if ptr == nil {
|
||||||
|
w.str = append(w.str, 0x80)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return writeBigInt(ptr, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeBigIntNoPtr(val reflect.Value, w *encbuf) error {
|
func writeBigIntNoPtr(val reflect.Value, w *encbuf) error {
|
||||||
|
@ -196,6 +196,7 @@ var encTests = []encTest{
|
|||||||
{val: (*uint)(nil), output: "80"},
|
{val: (*uint)(nil), output: "80"},
|
||||||
{val: (*string)(nil), output: "80"},
|
{val: (*string)(nil), output: "80"},
|
||||||
{val: (*[]byte)(nil), output: "80"},
|
{val: (*[]byte)(nil), output: "80"},
|
||||||
|
{val: (*big.Int)(nil), output: "80"},
|
||||||
{val: (*[]string)(nil), output: "C0"},
|
{val: (*[]string)(nil), output: "C0"},
|
||||||
{val: (*[]interface{})(nil), output: "C0"},
|
{val: (*[]interface{})(nil), output: "C0"},
|
||||||
{val: (*[]struct{ uint })(nil), output: "C0"},
|
{val: (*[]struct{ uint })(nil), output: "C0"},
|
||||||
|
Loading…
Reference in New Issue
Block a user