Skip to content

Commit

Permalink
Merge pull request #490 from vechain/randomized-scheduler
Browse files Browse the repository at this point in the history
Randomized scheduler
  • Loading branch information
libotony authored Oct 29, 2021
2 parents 11ae949 + 214c5f0 commit cef4268
Show file tree
Hide file tree
Showing 25 changed files with 1,790 additions and 332 deletions.
4 changes: 4 additions & 0 deletions block/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import (
"github.com/vechain/thor/tx"
)

const (
ComplexSigSize = 81 + 65
)

// Block is an immutable block type.
type Block struct {
header *Header
Expand Down
165 changes: 153 additions & 12 deletions block/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@
package block_test

import (
"fmt"
"math/rand"
"testing"
"time"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
"github.com/stretchr/testify/assert"
"github.com/vechain/thor/block"
. "github.com/vechain/thor/block"
"github.com/vechain/thor/thor"
"github.com/vechain/thor/tx"
)

func TestBlock(t *testing.T) {

tx1 := new(tx.Builder).Clause(tx.NewClause(&thor.Address{})).Clause(tx.NewClause(&thor.Address{})).Build()
tx2 := new(tx.Builder).Clause(tx.NewClause(nil)).Build()

Expand Down Expand Up @@ -51,12 +52,8 @@ func TestBlock(t *testing.T) {
h := block.Header()

txs := block.Transactions()
body := block.Body()
txsRootHash := txs.RootHash()

fmt.Println(h.ID())

assert.Equal(t, body.Txs, txs)
assert.Equal(t, Compose(h, txs), block)
assert.Equal(t, gasLimit, h.GasLimit())
assert.Equal(t, gasUsed, h.GasUsed())
Expand All @@ -74,15 +71,9 @@ func TestBlock(t *testing.T) {
block = block.WithSignature(sig)

data, _ := rlp.EncodeToBytes(block)
fmt.Println(Raw(data).DecodeHeader())
fmt.Println(Raw(data).DecodeBody())

fmt.Println(block.Size())

b := Block{}
rlp.DecodeBytes(data, &b)
fmt.Println(b.Header().ID())
fmt.Println(&b)

block = new(Builder).
GasUsed(gasUsed).
Expand All @@ -96,10 +87,160 @@ func TestBlock(t *testing.T) {
TransactionFeatures(1).
Build()

sig, _ = crypto.Sign(block.Header().SigningHash().Bytes(), key)
block = block.WithSignature(sig)

assert.Equal(t, tx.Features(1), block.Header().TxsFeatures())
data, _ = rlp.EncodeToBytes(block)
var bx Block
assert.Nil(t, rlp.DecodeBytes(data, &bx))
assert.Equal(t, block.Header().ID(), bx.Header().ID())
assert.Equal(t, block.Header().TxsFeatures(), bx.Header().TxsFeatures())
}

func TestHeaderEncoding(t *testing.T) {
var sig [65]byte
rand.Read(sig[:])

block := new(Builder).Build().WithSignature(sig[:])
h := block.Header()

bytes, err := rlp.EncodeToBytes(h)
if err != nil {
t.Fatal(err)
}

var hh Header
err = rlp.DecodeBytes(bytes, &hh)
if err != nil {
t.Fatal(err)
}

bytes = append(bytes, []byte("just trailing")...)
var hhh Header
err = rlp.DecodeBytes(bytes, &hhh)
assert.EqualError(t, err, "rlp: input contains more than one value")

var proof [81]byte
var alpha [32]byte
rand.Read(proof[:])
rand.Read(alpha[:])

complex, err := NewComplexSignature(sig[:], proof[:])
if err != nil {
t.Fatal(err)
}

b1 := new(Builder).Alpha(alpha[:]).Build().WithSignature(complex[:])
bs1, err := rlp.EncodeToBytes(b1.Header())
if err != nil {
t.Fatal(err)
}

var h1 Header
err = rlp.DecodeBytes(bs1, &h1)
if err != nil {
t.Fatal(err)
}
}

func TestEncodingBadExtension(t *testing.T) {
var sig [65]byte
rand.Read(sig[:])

block := new(Builder).Build().WithSignature(sig[:])
h := block.Header()

bytes, err := rlp.EncodeToBytes(h)
if err != nil {
t.Fatal(err)
}

var h1 Header
err = rlp.DecodeBytes(bytes, &h1)
if err != nil {
t.Fatal(err)
}

data, _, err := rlp.SplitList(bytes)
if err != nil {
t.Fatal(err)
}
count, err := rlp.CountValues(data)
if err != nil {
t.Fatal(err)
}
// backward compatiability,required to be trimmed
assert.EqualValues(t, 10, count)

var raws []rlp.RawValue
_ = rlp.DecodeBytes(bytes, &raws)
d, _ := rlp.EncodeToBytes(&struct {
Alpha []byte
}{
[]byte{},
})
raws = append(raws, d)
b, _ := rlp.EncodeToBytes(raws)

var h2 Header
err = rlp.DecodeBytes(b, &h2)
assert.EqualError(t, err, "rlp: extension must be trimmed")
}

func TestEncodingExtension(t *testing.T) {
var sig [block.ComplexSigSize]byte
var alpha [32]byte
rand.Read(sig[:])
rand.Read(alpha[:])

block := new(Builder).Alpha(alpha[:]).Build().WithSignature(sig[:])
h := block.Header()

bytes, err := rlp.EncodeToBytes(h)
if err != nil {
t.Fatal(err)
}

var hh Header
err = rlp.DecodeBytes(bytes, &hh)
if err != nil {
t.Fatal(err)
}

data, _, err := rlp.SplitList(bytes)
if err != nil {
t.Fatal(err)
}
count, err := rlp.CountValues(data)
if err != nil {
t.Fatal(err)
}
assert.EqualValues(t, 11, count)
}

func TestCodingCompatibility(t *testing.T) {
raw := hexutil.MustDecode("0xf8e0a0000000000000000000000000000000000000000000000000000000000000000080809400000000000000000000000000000000000000008080a045b0cfc220ceec5b7c1c62c4d4193d38e4eba48e8815729ce75f9c0ab0e4c1c0a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b841e95a07bda136baa1181f32fba25b8dec156dee373781fdc7d24acd5e60ebc104c04b397ee7a67953e2d10acc4835343cd949a73e7e58db1b92f682db62e793c412")

var h0 Header
err := rlp.DecodeBytes(raw, &h0)
if err != nil {
t.Fatal(err)
}

bytes, err := rlp.EncodeToBytes(&h0)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, raw, bytes)

data, _, err := rlp.SplitList(bytes)
if err != nil {
t.Fatal(err)
}
count, err := rlp.CountValues(data)
if err != nil {
t.Fatal(err)
}
assert.EqualValues(t, 10, count)
}
6 changes: 6 additions & 0 deletions block/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ func (b *Builder) TransactionFeatures(features tx.Features) *Builder {
return b
}

// Alpha set the alpha.
func (b *Builder) Alpha(alpha []byte) *Builder {
b.headerBody.Extension.Alpha = append([]byte(nil), alpha...)
return b
}

// Build build a block object.
func (b *Builder) Build() *Block {
header := Header{body: b.headerBody}
Expand Down
40 changes: 40 additions & 0 deletions block/complex_signature.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) 2020 The VeChainThor developers

// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying
// file LICENSE or <https://www.gnu.org/licenses/lgpl-3.0.html>

package block

import (
"errors"
)

// ComplexSignature is the signature composed by[ECDSA(Secp256k1) Signature(65 bytes)+VRF Proof(81 bytes)]
type ComplexSignature []byte

// NewComplexSignature creates a new signature.
func NewComplexSignature(signature, proof []byte) (ComplexSignature, error) {
if len(signature) != 65 {
return nil, errors.New("invalid signature length, 65 bytes required")
}
if len(proof) != 81 {
return nil, errors.New("invalid proof length, 81 bytes required")
}

var ms ComplexSignature
ms = make([]byte, 0, ComplexSigSize)
ms = append(ms, signature...)
ms = append(ms, proof...)

return ms, nil
}

// Signature returns the ECDSA signature.
func (ms ComplexSignature) Signature() []byte {
return ms[:65]
}

// Proof returns the VRF proof.
func (ms ComplexSignature) Proof() []byte {
return ms[65:]
}
50 changes: 50 additions & 0 deletions block/extension.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) 2020 The VeChainThor developers

// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying
// file LICENSE or <https://www.gnu.org/licenses/lgpl-3.0.html>

package block

import (
"errors"
"io"

"github.com/ethereum/go-ethereum/rlp"
)

type extension struct {
Alpha []byte
}

type _extension extension

// EncodeRLP implements rlp.Encoder.
func (ex *extension) EncodeRLP(w io.Writer) error {
// trim extension before VIP214
// this is mainly for backward compatibility
if len(ex.Alpha) == 0 {
return nil
}
return rlp.Encode(w, (*_extension)(ex))
}

// DecodeRLP implements rlp.Decoder.
func (ex *extension) DecodeRLP(s *rlp.Stream) error {
var obj _extension
if err := s.Decode(&obj); err != nil {
// Error(end-of-list) means this field is not present, return default value
// for backward compatibility
if err == rlp.EOL {
*ex = extension{
nil,
}
return nil
}
return err
}
if len(obj.Alpha) == 0 {
return errors.New("rlp: extension must be trimmed")
}
*ex = extension(obj)
return nil
}
Loading

0 comments on commit cef4268

Please sign in to comment.