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

Blob Serialisation #92

Merged
merged 37 commits into from
May 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
0ac53e8
sharding/client: Add utils.go for blob serialization(#92)
Apr 18, 2018
a83b6fd
sharding/client: Changing Validate Body(#92)
Apr 22, 2018
3e357a9
sharding/client: Adding Parse Blob(#92)
Apr 22, 2018
c36155c
sharding/client: Add conditions for terminal chunks(#92)
Apr 22, 2018
c01612f
sharding/client: Change to serialize blobs(#92)
May 1, 2018
ec2408c
sharding/client: Adding deserialize blobs(#92)
May 2, 2018
bf04ddb
sharding/client: Fixing deserializeblobs(#92)
May 2, 2018
c1ff070
sharding/client: Adding Main serialize function(#92)
May 2, 2018
bc174f3
sharding/client: Cleaning Up and adding errors(#92)
May 2, 2018
19aa0eb
sharding/client: Make serialization similar to JSON marshalling(#92)
May 3, 2018
f38af88
sharding/client: Finish changing Deserializebody(#92)
May 3, 2018
4953c2e
sharding/client: Adding new comments to improve clarity(#92)
May 3, 2018
1e45e34
sharding/client: Adding tests and modifying utils(#92)
May 4, 2018
7ac8bba
sharding/client: Fixing Tests (#92)
May 4, 2018
8871e42
sharding/client : Adding Size Test (#92)
May 4, 2018
85bcb3b
sharding/client: Cleaning up and refining tests(#92)
May 4, 2018
eb62dc6
sharding/client: Removing errors(#92)
May 4, 2018
8bfd22e
sharding/utils: Shifting to utils package(#92)
May 8, 2018
dbac529
sharding/utils: Fixed serialization tests(#92)
May 8, 2018
d49086a
sharding/utils : Adding Collation Methods (#92)
May 8, 2018
8568d34
sharding: Cleaning up tests (#92)
May 8, 2018
ce18eef
sharding: Removing Test (#92)
May 8, 2018
89f8544
sharding/utils: Fix Lint (#92)
May 8, 2018
c1b5d04
sharding/utils: Changing from interfaces to rawblobs(#92)
May 14, 2018
4470434
sharding/utils: Got Tests working again (#92)
May 14, 2018
eb582cb
sharding: Fix tests and clean up(#92)
May 14, 2018
798666a
sharding/utils : Adding RLP encoding (#92)
May 15, 2018
d1174fa
sharding: Fixing tests in util package (#92)
May 15, 2018
fafc95a
sharding: Adding roundtrip tests for tx serialization(#92)
May 15, 2018
c800d30
sharding: Adding comments to functions(#92)
May 15, 2018
a140f83
sharding: Cleaning up (#92)
May 15, 2018
434c511
sharding: Made Requested Changes(#92)
May 16, 2018
b906483
sharding: Removing pointer receiver(#92)
May 16, 2018
48000aa
sharding: fix up comment formatting in marshal and marshal_test.go
rauljordan May 16, 2018
d967118
sharding: Cleaning up after merge conflicts(#92)
May 16, 2018
5f0f542
sharding: Adding colon(#92)
May 16, 2018
6a2ebd3
sharding: Fix Lint (#92)
May 16, 2018
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
85 changes: 85 additions & 0 deletions sharding/collation.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package sharding

import (
"fmt"
"math"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/sharding/utils"
)

// Collation base struct.
Expand Down Expand Up @@ -38,6 +41,8 @@ type collationHeaderData struct {
ProposerSignature []byte // the proposer's signature for calculating collation hash.
}

var collationSizelimit = int64(math.Pow(float64(2), float64(20)))

// NewCollation initializes a collation and leaves it up to clients to serialize, deserialize
// and provide the body and transactions upon creation.
func NewCollation(header *CollationHeader, body []byte, transactions []*types.Transaction) *Collation {
Expand Down Expand Up @@ -105,3 +110,83 @@ func (c *Collation) CalculateChunkRoot() {
chunkRoot := common.BytesToHash(c.body)
c.header.data.ChunkRoot = &chunkRoot
}

// CreateRawBlobs creates raw blobs from transactions.
func (c Collation) CreateRawBlobs() ([]*utils.RawBlob, error) {

// It does not skip evm execution by default
blobs := make([]*utils.RawBlob, len(c.transactions))
for i := 0; i < len(c.transactions); i++ {

err := error(nil)
blobs[i], err = utils.NewRawBlob(c.transactions[i], false)

if err != nil {
return nil, fmt.Errorf("Creation of raw blobs from transactions failed: %v", err)
}

}

return blobs, nil

}

// ConvertBackToTx converts raw blobs back to their original transactions.
func ConvertBackToTx(rawBlobs []utils.RawBlob) ([]*types.Transaction, error) {

blobs := make([]*types.Transaction, len(rawBlobs))

for i := 0; i < len(rawBlobs); i++ {

blobs[i] = types.NewTransaction(0, common.HexToAddress("0x"), nil, 0, nil, nil)

err := utils.ConvertFromRawBlob(&rawBlobs[i], blobs[i])
if err != nil {
return nil, fmt.Errorf("Creation of transactions from raw blobs failed: %v", err)
}
}
return blobs, nil

}

// Serialize method serializes the collation body to a byte array.
func (c *Collation) Serialize() ([]byte, error) {

blobs, err := c.CreateRawBlobs()

if err != nil {
return nil, fmt.Errorf("%v", err)
}

serializedTx, err := utils.Serialize(blobs)

if err != nil {
return nil, fmt.Errorf("%v", err)
}

if int64(len(serializedTx)) > collationSizelimit {

return nil, fmt.Errorf("The serialized body exceeded the collation size limit: %v", serializedTx)

}

return serializedTx, nil

}

// Deserialize takes a byte array and converts its back to its original transactions.
func Deserialize(serialisedBlob []byte) (*[]*types.Transaction, error) {

deserializedBlobs, err := utils.Deserialize(serialisedBlob)
if err != nil {
return nil, fmt.Errorf("%v", err)
}

txs, err := ConvertBackToTx(deserializedBlobs)

if err != nil {
return nil, fmt.Errorf("%v", err)
}

return &txs, nil
}
96 changes: 90 additions & 6 deletions sharding/collation_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
package sharding

import (
"bytes"
"math/big"
"reflect"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)

// fieldAccess is to access unexported fields in structs in another package
func fieldAccess(i interface{}, fields []string) reflect.Value {
val := reflect.ValueOf(i)
for i := 0; i < len(fields); i++ {
val = reflect.Indirect(val).FieldByName(fields[i])
}
return val

}
func TestCollation_Transactions(t *testing.T) {
header := NewCollationHeader(big.NewInt(1), nil, big.NewInt(1), nil, []byte{})
body := []byte{}
Expand All @@ -27,16 +38,89 @@ func TestCollation_Transactions(t *testing.T) {
}
}

func TestCollation_ProposerAddress(t *testing.T) {
proposerAddr := common.BytesToAddress([]byte("proposer"))
header := NewCollationHeader(big.NewInt(1), nil, big.NewInt(1), &proposerAddr, []byte{})
//TODO: Add test for converting *types.Transaction into raw blobs

//Tests that Transactions can be serialised
func TestSerialize_Deserialize(t *testing.T) {

header := NewCollationHeader(big.NewInt(1), nil, big.NewInt(1), nil, []byte{})
body := []byte{}
transactions := []*types.Transaction{
makeTxWithGasLimit(0),
makeTxWithGasLimit(5),
makeTxWithGasLimit(20),
makeTxWithGasLimit(100),
}

c := NewCollation(header, body, transactions)

tx := c.transactions

results, err := c.Serialize()

collation := NewCollation(header, body, nil)
if err != nil {
t.Errorf("Unable to Serialize transactions, %v", err)
}

deserializedTxs, err := Deserialize(results)

if err != nil {
t.Errorf("Unable to deserialize collation body, %v", err)
}

if collation.ProposerAddress().String() != proposerAddr.String() {
t.Errorf("initialized collation does not contain correct proposer address")
if len(tx) != len(*deserializedTxs) {
t.Errorf("Transaction length is different before and after serialization: %v, %v", len(tx), len(*deserializedTxs))
}

for i := 0; i < len(tx); i++ {

beforeSerialization := tx[i]
afterDeserialization := (*deserializedTxs)[i]

if beforeSerialization.Nonce() != afterDeserialization.Nonce() {

t.Errorf("Data before serialization and after deserialization are not the same ,AccountNonce: %v, %v", beforeSerialization.Nonce(), afterDeserialization.Nonce())

}

if beforeSerialization.Gas() != afterDeserialization.Gas() {

t.Errorf("Data before serialization and after deserialization are not the same ,GasLimit: %v, %v", beforeSerialization.Gas(), afterDeserialization.Gas())

}

if beforeSerialization.GasPrice().Cmp(afterDeserialization.GasPrice()) != 0 {

t.Errorf("Data before serialization and after deserialization are not the same ,Price: %v, %v", beforeSerialization.GasPrice(), afterDeserialization.GasPrice())

}

beforeAddress := reflect.ValueOf(beforeSerialization.To())
afterAddress := reflect.ValueOf(afterDeserialization.To())

if reflect.DeepEqual(beforeAddress, afterAddress) {

t.Errorf("Data before serialization and after deserialization are not the same ,Recipient: %v, %v", beforeAddress, afterAddress)

}

if beforeSerialization.Value().Cmp(afterDeserialization.Value()) != 0 {

t.Errorf("Data before serialization and after deserialization are not the same ,Amount: %v, %v", beforeSerialization.Value(), afterDeserialization.Value())

}

beforeData := beforeSerialization.Data()
afterData := afterDeserialization.Data()

if !bytes.Equal(beforeData, afterData) {

t.Errorf("Data before serialization and after deserialization are not the same ,Payload: %v, %v", beforeData, afterData)

}

}

}

func makeTxWithGasLimit(gl uint64) *types.Transaction {
Expand Down
Loading