aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeterminant <tederminant@gmail.com>2020-08-02 18:44:47 -0400
committerDeterminant <tederminant@gmail.com>2020-08-02 18:44:47 -0400
commit746a107e2a7bb1f66049240d320e29d0a0536eae (patch)
tree741f2bb322df16d15ee1a8eff428c54c1b65fbd7
parent489ecc0c53ef8279863e58469fa161ade273119f (diff)
make block-format backward-compatible and future-proofv0.2.11
-rw-r--r--core/types/block.go61
-rw-r--r--examples/block/main.go146
-rw-r--r--go.sum3
3 files changed, 204 insertions, 6 deletions
diff --git a/core/types/block.go b/core/types/block.go
index 2fdc904..fcbd8ab 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -18,6 +18,7 @@
package types
import (
+ "bytes"
"encoding/binary"
"fmt"
"io"
@@ -149,6 +150,7 @@ type Block struct {
header *Header
uncles []*Header
transactions Transactions
+ extdata []byte
// caches
hash atomic.Value
@@ -184,6 +186,14 @@ type extblock struct {
Uncles []*Header
}
+type myextblock struct {
+ Header *Header
+ Txs []*Transaction
+ Uncles []*Header
+ VersionNumber uint32
+ ExtData []byte
+}
+
// [deprecated by eth/63]
// "storage" block encoding. used for database.
type storageblock struct {
@@ -258,18 +268,35 @@ func CopyHeader(h *Header) *Header {
// DecodeRLP decodes the Ethereum
func (b *Block) DecodeRLP(s *rlp.Stream) error {
+ bs, _ := s.Raw()
+ copied := make([]byte, len(bs))
+ copy(copied, bs)
+ ss := rlp.NewStream(bytes.NewReader(bs), 0)
+
var eb extblock
- _, size, _ := s.Kind()
- if err := s.Decode(&eb); err != nil {
- return err
+ _, size, _ := ss.Kind()
+ if err := ss.Decode(&eb); err != nil {
+ var meb myextblock
+ ss = rlp.NewStream(bytes.NewReader(copied), 0)
+ if err := ss.Decode(&meb); err != nil {
+ return err
+ }
+ b.header, b.uncles, b.transactions = meb.Header, meb.Uncles, meb.Txs
+ b.extdata = meb.ExtData
+ } else {
+ b.header, b.uncles, b.transactions = eb.Header, eb.Uncles, eb.Txs
+ b.extdata = nil
}
- b.header, b.uncles, b.transactions = eb.Header, eb.Uncles, eb.Txs
b.size.Store(common.StorageSize(rlp.ListSize(size)))
return nil
}
-// EncodeRLP serializes b into the Ethereum RLP block format.
-func (b *Block) EncodeRLP(w io.Writer) error {
+func (b *Block) RawExtraData() []byte {
+ return b.extdata
+}
+
+// EncodeRLPEth serializes b into the Ethereum RLP block format.
+func (b *Block) EncodeRLPEth(w io.Writer) error {
return rlp.Encode(w, extblock{
Header: b.header,
Txs: b.transactions,
@@ -277,6 +304,28 @@ func (b *Block) EncodeRLP(w io.Writer) error {
})
}
+func (b *Block) EncodeRLPTest(w io.Writer, ver uint32, data []byte) error {
+ return rlp.Encode(w, myextblock{
+ Header: b.header,
+ Txs: b.transactions,
+ Uncles: b.uncles,
+ VersionNumber: ver,
+ ExtData: data,
+ })
+}
+
+// EncodeRLP serializes b into an extended format.
+func (b *Block) EncodeRLP(w io.Writer) error {
+ return rlp.Encode(w, myextblock{
+ Header: b.header,
+ Txs: b.transactions,
+ Uncles: b.uncles,
+ VersionNumber: 0,
+ // TODO: add actual extra data for the current version
+ ExtData: []byte{},
+ })
+}
+
// [deprecated by eth/63]
func (b *StorageBlock) DecodeRLP(s *rlp.Stream) error {
var sb storageblock
diff --git a/examples/block/main.go b/examples/block/main.go
new file mode 100644
index 0000000..d9ea16b
--- /dev/null
+++ b/examples/block/main.go
@@ -0,0 +1,146 @@
+package main
+
+import (
+ "bytes"
+ "crypto/rand"
+ "fmt"
+ "github.com/ava-labs/coreth"
+ "github.com/ava-labs/coreth/core"
+ "github.com/ava-labs/coreth/core/types"
+ "github.com/ava-labs/coreth/eth"
+ "github.com/ava-labs/coreth/params"
+ "github.com/ava-labs/go-ethereum/common"
+ "github.com/ava-labs/go-ethereum/common/hexutil"
+ "github.com/ava-labs/go-ethereum/rlp"
+ "math/big"
+)
+
+func checkError(err error) {
+ if err != nil {
+ panic(err)
+ }
+}
+
+func main() {
+ // configure the chain
+ config := eth.DefaultConfig
+ config.ManualCanonical = true
+ chainConfig := &params.ChainConfig{
+ ChainID: big.NewInt(1),
+ HomesteadBlock: big.NewInt(0),
+ DAOForkBlock: big.NewInt(0),
+ DAOForkSupport: true,
+ EIP150Block: big.NewInt(0),
+ EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
+ EIP155Block: big.NewInt(0),
+ EIP158Block: big.NewInt(0),
+ ByzantiumBlock: big.NewInt(0),
+ ConstantinopleBlock: big.NewInt(0),
+ PetersburgBlock: big.NewInt(0),
+ IstanbulBlock: nil,
+ Ethash: nil,
+ }
+
+ // configure the genesis block
+ genBalance := big.NewInt(100000000000000000)
+ genKey, _ := coreth.NewKey(rand.Reader)
+
+ config.Genesis = &core.Genesis{
+ Config: chainConfig,
+ Nonce: 0,
+ Number: 0,
+ ExtraData: hexutil.MustDecode("0x00"),
+ GasLimit: 100000000,
+ Difficulty: big.NewInt(0),
+ Alloc: core.GenesisAlloc{genKey.Address: {Balance: genBalance}},
+ }
+
+ // grab the control of block generation and disable auto uncle
+ config.Miner.ManualMining = true
+ config.Miner.DisableUncle = true
+
+ chain := coreth.NewETHChain(&config, nil, nil, nil)
+ buff := new(bytes.Buffer)
+ blk := chain.GetGenesisBlock()
+ err := blk.EncodeRLPEth(buff)
+ buff.WriteString("somesuffix")
+ checkError(err)
+ var blk2 *types.Block
+ blk2 = new(types.Block)
+ fmt.Println(buff.Len())
+ fmt.Println(common.ToHex(buff.Bytes()))
+
+ err = rlp.Decode(buff, blk2)
+ fmt.Println(buff.Len())
+ checkError(err)
+ buff.Reset()
+ err = blk2.EncodeRLPEth(buff)
+ checkError(err)
+ fmt.Println(buff.Len())
+ fmt.Println(common.ToHex(buff.Bytes()))
+
+ err = rlp.Decode(buff, blk2)
+ fmt.Println(buff.Len())
+ checkError(err)
+ buff.Reset()
+ err = blk2.EncodeRLP(buff)
+ checkError(err)
+ buff.WriteString("somesuffix")
+ fmt.Println(buff.Len())
+ fmt.Println(common.ToHex(buff.Bytes()))
+
+ err = rlp.Decode(buff, blk2)
+ fmt.Println(buff.Len())
+ checkError(err)
+ buff.Reset()
+ err = blk2.EncodeRLP(buff)
+ checkError(err)
+ fmt.Println(buff.Len())
+ fmt.Println(common.ToHex(buff.Bytes()))
+
+ err = rlp.Decode(buff, blk2)
+ fmt.Println(buff.Len())
+ checkError(err)
+ buff.Reset()
+ extra, err := rlp.EncodeToBytes("test extra data")
+ err = blk2.EncodeRLPTest(buff, 0xffffffff, extra)
+ checkError(err)
+ buff.WriteString("somesuffix")
+ fmt.Println(buff.Len())
+ fmt.Println(common.ToHex(buff.Bytes()))
+
+ err = rlp.Decode(buff, blk2)
+ fmt.Println(buff.Len(), (string)(blk2.RawExtraData()))
+ checkError(err)
+ buff.Reset()
+ type NestedData struct {
+ A uint16
+ B uint16
+ S string
+ }
+ type MyData struct {
+ X uint32
+ Y uint32
+ Msg string
+ Inner NestedData
+ }
+ extra, err = rlp.EncodeToBytes(MyData{
+ X: 4200, Y: 4300, Msg: "hello", Inner: NestedData{A: 1, B: 2, S: "world"},
+ })
+ checkError(err)
+ err = blk2.EncodeRLPTest(buff, 0xfffffffe, extra)
+ checkError(err)
+ decoded1 := new(string)
+ err = rlp.DecodeBytes(blk2.RawExtraData(), decoded1)
+ checkError(err)
+ fmt.Println(buff.Len(), decoded1)
+ fmt.Println(common.ToHex(buff.Bytes()))
+
+ err = rlp.Decode(buff, blk2)
+ checkError(err)
+ decoded2 := new(MyData)
+ err = rlp.DecodeBytes(blk2.RawExtraData(), decoded2)
+ checkError(err)
+ fmt.Println(buff.Len(), decoded2)
+ buff.Reset()
+}
diff --git a/go.sum b/go.sum
index ff050d6..e8621cb 100644
--- a/go.sum
+++ b/go.sum
@@ -126,8 +126,10 @@ github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@@ -309,6 +311,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=