commit
506faf2985
@ -0,0 +1,50 @@ |
|||||||
|
package blockfactory |
||||||
|
|
||||||
|
import ( |
||||||
|
"math/big" |
||||||
|
|
||||||
|
"github.com/harmony-one/harmony/block" |
||||||
|
blockif "github.com/harmony-one/harmony/block/interface" |
||||||
|
v0 "github.com/harmony-one/harmony/block/v0" |
||||||
|
v1 "github.com/harmony-one/harmony/block/v1" |
||||||
|
"github.com/harmony-one/harmony/internal/params" |
||||||
|
) |
||||||
|
|
||||||
|
// Factory is a data structure factory for a specific chain configuration.
|
||||||
|
type Factory interface { |
||||||
|
// NewHeader creates a new, empty header object for the given epoch.
|
||||||
|
NewHeader(epoch *big.Int) *block.Header |
||||||
|
} |
||||||
|
|
||||||
|
type factory struct { |
||||||
|
chainConfig *params.ChainConfig |
||||||
|
} |
||||||
|
|
||||||
|
// NewFactory creates a new factory for the given chain configuration.
|
||||||
|
func NewFactory(chainConfig *params.ChainConfig) Factory { |
||||||
|
return &factory{chainConfig: chainConfig} |
||||||
|
} |
||||||
|
|
||||||
|
func (f *factory) NewHeader(epoch *big.Int) *block.Header { |
||||||
|
var impl blockif.Header |
||||||
|
switch { |
||||||
|
case epoch.Cmp(f.chainConfig.CrossLinkEpoch) >= 0: |
||||||
|
impl = v1.NewHeader() |
||||||
|
default: |
||||||
|
impl = v0.NewHeader() |
||||||
|
} |
||||||
|
return &block.Header{impl} |
||||||
|
} |
||||||
|
|
||||||
|
// Factories corresponding to well-known chain configurations.
|
||||||
|
var ( |
||||||
|
ForTest = NewFactory(params.TestChainConfig) |
||||||
|
ForTestnet = NewFactory(params.TestnetChainConfig) |
||||||
|
ForMainnet = NewFactory(params.MainnetChainConfig) |
||||||
|
) |
||||||
|
|
||||||
|
// NewTestHeader creates a new, empty header object for epoch 0 using the test
|
||||||
|
// factory. Use for unit tests.
|
||||||
|
func NewTestHeader() *block.Header { |
||||||
|
return ForTest.NewHeader(new(big.Int)) |
||||||
|
} |
@ -0,0 +1,538 @@ |
|||||||
|
package block |
||||||
|
|
||||||
|
import ( |
||||||
|
"bytes" |
||||||
|
"reflect" |
||||||
|
"testing" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/rlp" |
||||||
|
|
||||||
|
blockif "github.com/harmony-one/harmony/block/interface" |
||||||
|
v0 "github.com/harmony-one/harmony/block/v0" |
||||||
|
v1 "github.com/harmony-one/harmony/block/v1" |
||||||
|
) |
||||||
|
|
||||||
|
func TestHeader_EncodeRLP(t *testing.T) { |
||||||
|
type fields struct { |
||||||
|
HeaderInterface blockif.Header |
||||||
|
} |
||||||
|
tests := []struct { |
||||||
|
name string |
||||||
|
fields fields |
||||||
|
want []byte |
||||||
|
wantErr bool |
||||||
|
}{ |
||||||
|
{ |
||||||
|
"v0", |
||||||
|
fields{v0.NewHeader()}, |
||||||
|
[]byte{ |
||||||
|
// BEGIN 586-byte Header
|
||||||
|
0xf9, 0x02, 0x4a, |
||||||
|
0xa0, // 32-byte ParentHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x94, // 20-byte Coinbase
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte Root
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte TxHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte ReceiptHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xb9, 0x01, 0x00, // 256-byte Bloom
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte Number
|
||||||
|
0x80, // 0-byte GasLimit
|
||||||
|
0x80, // 0-byte GasUsed
|
||||||
|
0x80, // 0-byte Time
|
||||||
|
0x80, // 0-byte Extra
|
||||||
|
0xa0, // 32-byte MixDigest
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte ViewID
|
||||||
|
0x80, // 0-byte Epoch
|
||||||
|
0x80, // 0-byte ShardID
|
||||||
|
0xb8, 0x60, // 96-byte LastCommitSignature
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte LastCommitBitmap
|
||||||
|
0xa0, // 32-byte ShardStateHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte ShardState
|
||||||
|
// END Header
|
||||||
|
}, |
||||||
|
false, |
||||||
|
}, |
||||||
|
{ |
||||||
|
"v1", |
||||||
|
fields{v1.NewHeader()}, |
||||||
|
[]byte{ |
||||||
|
// BEGIN 669-byte tagged RLP envelope
|
||||||
|
0xf9, 0x02, 0x9d, |
||||||
|
0x87, // 7-byte tagged RLP signature
|
||||||
|
'H', 'm', 'n', 'y', 'T', 'g', 'd', |
||||||
|
0x82, // 2-byte v1 header tag
|
||||||
|
'v', '1', |
||||||
|
// BEGIN 655-byte Header
|
||||||
|
0xf9, 0x02, 0x8f, |
||||||
|
0xa0, // 32-byte ParentHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x94, // 20-byte Coinbase
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte Root
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte TxHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte ReceiptHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte OutgoingReceiptHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte IncomingReceiptHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xb9, 0x01, 0x00, // 256-byte Bloom
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte Number
|
||||||
|
0x80, // 0-byte GasLimit
|
||||||
|
0x80, // 0-byte GasUsed
|
||||||
|
0x80, // 0-byte Time
|
||||||
|
0x80, // 0-byte Extra
|
||||||
|
0xa0, // 32-byte MixDigest
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte ViewID
|
||||||
|
0x80, // 0-byte Epoch
|
||||||
|
0x80, // 0-byte ShardID
|
||||||
|
0xb8, 0x60, // 96-byte LastCommitSignature
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte LastCommitBitmap
|
||||||
|
0xa0, // 32-byte ShardStateHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte Vrf
|
||||||
|
0x80, // 0-byte Vdf
|
||||||
|
0x80, // 0-byte ShardState
|
||||||
|
0x80, // 0-byte CrossLinks
|
||||||
|
// END Header
|
||||||
|
// END tagged RLP envelope
|
||||||
|
}, |
||||||
|
false, |
||||||
|
}, |
||||||
|
} |
||||||
|
for _, tt := range tests { |
||||||
|
t.Run(tt.name, func(t *testing.T) { |
||||||
|
h := &Header{Header: tt.fields.HeaderInterface} |
||||||
|
w := &bytes.Buffer{} |
||||||
|
err := h.EncodeRLP(w) |
||||||
|
if (err != nil) != tt.wantErr { |
||||||
|
t.Errorf("EncodeRLP() error = %v, wantErr %v", err, tt.wantErr) |
||||||
|
return |
||||||
|
} |
||||||
|
if got := w.Bytes(); bytes.Compare(got, tt.want) != 0 { |
||||||
|
t.Errorf("EncodeRLP() got %x", got) |
||||||
|
t.Errorf("EncodeRLP() want %x", tt.want) |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func TestHeader_DecodeRLP(t *testing.T) { |
||||||
|
type args struct { |
||||||
|
s *rlp.Stream |
||||||
|
} |
||||||
|
tests := []struct { |
||||||
|
name string |
||||||
|
args args |
||||||
|
want blockif.Header |
||||||
|
wantErr bool |
||||||
|
}{ |
||||||
|
{ |
||||||
|
"v0", |
||||||
|
args{rlp.NewStream(bytes.NewBuffer([]byte{ |
||||||
|
// BEGIN 586-byte Header
|
||||||
|
0xf9, 0x02, 0x4a, |
||||||
|
0xa0, // 32-byte ParentHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x94, // 20-byte Coinbase
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte Root
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte TxHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte ReceiptHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xb9, 0x01, 0x00, // 256-byte Bloom
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte Number
|
||||||
|
0x80, // 0-byte GasLimit
|
||||||
|
0x80, // 0-byte GasUsed
|
||||||
|
0x80, // 0-byte Time
|
||||||
|
0x80, // 0-byte Extra
|
||||||
|
0xa0, // 32-byte MixDigest
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte ViewID
|
||||||
|
0x80, // 0-byte Epoch
|
||||||
|
0x80, // 0-byte ShardID
|
||||||
|
0xb8, 0x60, // 96-byte LastCommitSignature
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte LastCommitBitmap
|
||||||
|
0xa0, // 32-byte ShardStateHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte ShardState
|
||||||
|
// END Header
|
||||||
|
}), 0)}, |
||||||
|
v0.NewHeader(), |
||||||
|
false, |
||||||
|
}, |
||||||
|
{ |
||||||
|
"v1", |
||||||
|
args{rlp.NewStream(bytes.NewBuffer([]byte{ |
||||||
|
// BEGIN 669-byte tagged RLP envelope
|
||||||
|
0xf9, 0x02, 0x9d, |
||||||
|
0x87, // 7-byte tagged RLP signature
|
||||||
|
'H', 'm', 'n', 'y', 'T', 'g', 'd', |
||||||
|
0x82, // 2-byte v1 header tag
|
||||||
|
'v', '1', |
||||||
|
// BEGIN 655-byte Header
|
||||||
|
0xf9, 0x02, 0x8f, |
||||||
|
0xa0, // 32-byte ParentHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x94, // 20-byte Coinbase
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte Root
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte TxHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte ReceiptHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte OutgoingReceiptHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xa0, // 32-byte IncomingReceiptHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0xb9, 0x01, 0x00, // 256-byte Bloom
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte Number
|
||||||
|
0x80, // 0-byte GasLimit
|
||||||
|
0x80, // 0-byte GasUsed
|
||||||
|
0x80, // 0-byte Time
|
||||||
|
0x80, // 0-byte Extra
|
||||||
|
0xa0, // 32-byte MixDigest
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte ViewID
|
||||||
|
0x80, // 0-byte Epoch
|
||||||
|
0x80, // 0-byte ShardID
|
||||||
|
0xb8, 0x60, // 96-byte LastCommitSignature
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte LastCommitBitmap
|
||||||
|
0xa0, // 32-byte ShardStateHash
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||||||
|
0x80, // 0-byte Vrf
|
||||||
|
0x80, // 0-byte Vdf
|
||||||
|
0x80, // 0-byte ShardState
|
||||||
|
0x80, // 0-byte CrossLinks
|
||||||
|
// END Header
|
||||||
|
// END tagged RLP envelope
|
||||||
|
}), 0)}, |
||||||
|
v1.NewHeader(), |
||||||
|
false, |
||||||
|
}, |
||||||
|
} |
||||||
|
for _, tt := range tests { |
||||||
|
t.Run(tt.name, func(t *testing.T) { |
||||||
|
h := &Header{} |
||||||
|
if err := h.DecodeRLP(tt.args.s); (err != nil) != tt.wantErr { |
||||||
|
t.Errorf("DecodeRLP() error = %v, wantErr %v", err, tt.wantErr) |
||||||
|
} |
||||||
|
if !compareHeaders(h.Header, tt.want) { |
||||||
|
t.Errorf("DecodeRLP() got %#v", h.Header) |
||||||
|
t.Errorf("DecodeRLP() want %#v", tt.want) |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func equal(x, y interface{}) bool { |
||||||
|
xv := reflect.ValueOf(x) |
||||||
|
yv := reflect.ValueOf(y) |
||||||
|
if xv.Type() == yv.Type() && xv.Type().Kind() == reflect.Slice && xv.Len() == 0 && yv.Len() == 0 { |
||||||
|
return true |
||||||
|
} |
||||||
|
return reflect.DeepEqual(x, y) |
||||||
|
} |
||||||
|
|
||||||
|
func compareHeaders(x, y blockif.Header) bool { |
||||||
|
return equal(x.ParentHash(), y.ParentHash()) && |
||||||
|
equal(x.Coinbase(), y.Coinbase()) && |
||||||
|
equal(x.Root(), y.Root()) && |
||||||
|
equal(x.TxHash(), y.TxHash()) && |
||||||
|
equal(x.ReceiptHash(), y.ReceiptHash()) && |
||||||
|
equal(x.OutgoingReceiptHash(), y.OutgoingReceiptHash()) && |
||||||
|
equal(x.IncomingReceiptHash(), y.IncomingReceiptHash()) && |
||||||
|
equal(x.Bloom(), y.Bloom()) && |
||||||
|
equal(x.Number(), y.Number()) && |
||||||
|
equal(x.GasLimit(), y.GasLimit()) && |
||||||
|
equal(x.GasUsed(), y.GasUsed()) && |
||||||
|
equal(x.Time(), y.Time()) && |
||||||
|
equal(x.Extra(), y.Extra()) && |
||||||
|
equal(x.MixDigest(), y.MixDigest()) && |
||||||
|
equal(x.ViewID(), y.ViewID()) && |
||||||
|
equal(x.Epoch(), y.Epoch()) && |
||||||
|
equal(x.ShardID(), y.ShardID()) && |
||||||
|
equal(x.LastCommitSignature(), y.LastCommitSignature()) && |
||||||
|
equal(x.LastCommitBitmap(), y.LastCommitBitmap()) && |
||||||
|
equal(x.ShardStateHash(), y.ShardStateHash()) && |
||||||
|
equal(x.Vrf(), y.Vrf()) && |
||||||
|
equal(x.Vdf(), y.Vdf()) && |
||||||
|
equal(x.ShardState(), y.ShardState()) && |
||||||
|
equal(x.CrossLinks(), y.CrossLinks()) |
||||||
|
} |
@ -0,0 +1,186 @@ |
|||||||
|
package block |
||||||
|
|
||||||
|
import ( |
||||||
|
"math/big" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
"github.com/ethereum/go-ethereum/core/types" |
||||||
|
) |
||||||
|
|
||||||
|
// HeaderFieldSetter is a header field setter.
|
||||||
|
//
|
||||||
|
// See NewHeaderWith for how it is used.
|
||||||
|
type HeaderFieldSetter struct { |
||||||
|
h *Header |
||||||
|
} |
||||||
|
|
||||||
|
// ParentHash sets the parent hash field.
|
||||||
|
func (s HeaderFieldSetter) ParentHash(newParentHash common.Hash) HeaderFieldSetter { |
||||||
|
s.h.SetParentHash(newParentHash) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// Coinbase sets the coinbase address field.
|
||||||
|
func (s HeaderFieldSetter) Coinbase(newCoinbase common.Address) HeaderFieldSetter { |
||||||
|
s.h.SetCoinbase(newCoinbase) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// Root sets the state trie root hash field.
|
||||||
|
func (s HeaderFieldSetter) Root(newRoot common.Hash) HeaderFieldSetter { |
||||||
|
s.h.SetRoot(newRoot) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// TxHash sets the transaction trie root hash field.
|
||||||
|
func (s HeaderFieldSetter) TxHash(newTxHash common.Hash) HeaderFieldSetter { |
||||||
|
s.h.SetTxHash(newTxHash) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// ReceiptHash sets the same-shard transaction receipt trie hash.
|
||||||
|
func (s HeaderFieldSetter) ReceiptHash(newReceiptHash common.Hash) HeaderFieldSetter { |
||||||
|
s.h.SetReceiptHash(newReceiptHash) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// OutgoingReceiptHash sets the egress transaction receipt trie hash.
|
||||||
|
func (s HeaderFieldSetter) OutgoingReceiptHash(newOutgoingReceiptHash common.Hash) HeaderFieldSetter { |
||||||
|
s.h.SetOutgoingReceiptHash(newOutgoingReceiptHash) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// IncomingReceiptHash sets the ingress transaction receipt trie hash.
|
||||||
|
func (s HeaderFieldSetter) IncomingReceiptHash(newIncomingReceiptHash common.Hash) HeaderFieldSetter { |
||||||
|
s.h.SetIncomingReceiptHash(newIncomingReceiptHash) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// Bloom sets the smart contract log Bloom filter for this block.
|
||||||
|
func (s HeaderFieldSetter) Bloom(newBloom types.Bloom) HeaderFieldSetter { |
||||||
|
s.h.SetBloom(newBloom) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// Number sets the block number.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (s HeaderFieldSetter) Number(newNumber *big.Int) HeaderFieldSetter { |
||||||
|
s.h.SetNumber(newNumber) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// GasLimit sets the gas limit for transactions in this block.
|
||||||
|
func (s HeaderFieldSetter) GasLimit(newGasLimit uint64) HeaderFieldSetter { |
||||||
|
s.h.SetGasLimit(newGasLimit) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// GasUsed sets the amount of gas used by transactions in this block.
|
||||||
|
func (s HeaderFieldSetter) GasUsed(newGasUsed uint64) HeaderFieldSetter { |
||||||
|
s.h.SetGasUsed(newGasUsed) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// Time sets the UNIX timestamp of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (s HeaderFieldSetter) Time(newTime *big.Int) HeaderFieldSetter { |
||||||
|
s.h.SetTime(newTime) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// Extra sets the extra data field of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (s HeaderFieldSetter) Extra(newExtra []byte) HeaderFieldSetter { |
||||||
|
s.h.SetExtra(newExtra) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// MixDigest sets the mixhash of this block.
|
||||||
|
func (s HeaderFieldSetter) MixDigest(newMixDigest common.Hash) HeaderFieldSetter { |
||||||
|
s.h.SetMixDigest(newMixDigest) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// ViewID sets the view ID in which the block was originally proposed.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (s HeaderFieldSetter) ViewID(newViewID *big.Int) HeaderFieldSetter { |
||||||
|
s.h.SetViewID(newViewID) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// Epoch sets the epoch number of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (s HeaderFieldSetter) Epoch(newEpoch *big.Int) HeaderFieldSetter { |
||||||
|
s.h.SetEpoch(newEpoch) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// ShardID sets the shard ID to which this block belongs.
|
||||||
|
func (s HeaderFieldSetter) ShardID(newShardID uint32) HeaderFieldSetter { |
||||||
|
s.h.SetShardID(newShardID) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// LastCommitSignature sets the FBFT commit group signature for the last block.
|
||||||
|
func (s HeaderFieldSetter) LastCommitSignature(newLastCommitSignature [96]byte) HeaderFieldSetter { |
||||||
|
s.h.SetLastCommitSignature(newLastCommitSignature) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// LastCommitBitmap sets the signatory bitmap of the previous block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (s HeaderFieldSetter) LastCommitBitmap(newLastCommitBitmap []byte) HeaderFieldSetter { |
||||||
|
s.h.SetLastCommitBitmap(newLastCommitBitmap) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// ShardStateHash sets the shard state hash.
|
||||||
|
func (s HeaderFieldSetter) ShardStateHash(newShardStateHash common.Hash) HeaderFieldSetter { |
||||||
|
s.h.SetShardStateHash(newShardStateHash) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// Vrf sets the output of the VRF for the epoch.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (s HeaderFieldSetter) Vrf(newVrf []byte) HeaderFieldSetter { |
||||||
|
s.h.SetVrf(newVrf) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// Vdf sets the output of the VDF for the epoch.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (s HeaderFieldSetter) Vdf(newVdf []byte) HeaderFieldSetter { |
||||||
|
s.h.SetVdf(newVdf) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// ShardState sets the RLP-encoded form of shard state
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (s HeaderFieldSetter) ShardState(newShardState []byte) HeaderFieldSetter { |
||||||
|
s.h.SetShardState(newShardState) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// CrossLinks sets the RLP-encoded form of non-beacon block headers chosen to be
|
||||||
|
// canonical by the beacon committee.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (s HeaderFieldSetter) CrossLinks(newCrossLinks []byte) HeaderFieldSetter { |
||||||
|
s.h.SetCrossLinks(newCrossLinks) |
||||||
|
return s |
||||||
|
} |
||||||
|
|
||||||
|
// Header returns the header whose fields have been set. Call this at the end
|
||||||
|
// of a field setter chain.
|
||||||
|
func (s HeaderFieldSetter) Header() *Header { |
||||||
|
return s.h |
||||||
|
} |
@ -0,0 +1,230 @@ |
|||||||
|
package blockif |
||||||
|
|
||||||
|
import ( |
||||||
|
"math/big" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
"github.com/ethereum/go-ethereum/core/types" |
||||||
|
"github.com/rs/zerolog" |
||||||
|
|
||||||
|
"github.com/harmony-one/harmony/shard" |
||||||
|
) |
||||||
|
|
||||||
|
// Header defines the block header interface.
|
||||||
|
type Header interface { |
||||||
|
// ParentHash is the header hash of the parent block. For the genesis block
|
||||||
|
// which has no parent by definition, this field is zeroed out.
|
||||||
|
ParentHash() common.Hash |
||||||
|
|
||||||
|
// SetParentHash sets the parent hash field.
|
||||||
|
SetParentHash(newParentHash common.Hash) |
||||||
|
|
||||||
|
// Coinbase is the address of the node that proposed this block and all
|
||||||
|
// transactions in it.
|
||||||
|
Coinbase() common.Address |
||||||
|
|
||||||
|
// SetCoinbase sets the coinbase address field.
|
||||||
|
SetCoinbase(newCoinbase common.Address) |
||||||
|
|
||||||
|
// Root is the state (account) trie root hash.
|
||||||
|
Root() common.Hash |
||||||
|
|
||||||
|
// SetRoot sets the state trie root hash field.
|
||||||
|
SetRoot(newRoot common.Hash) |
||||||
|
|
||||||
|
// TxHash is the transaction trie root hash.
|
||||||
|
TxHash() common.Hash |
||||||
|
|
||||||
|
// SetTxHash sets the transaction trie root hash field.
|
||||||
|
SetTxHash(newTxHash common.Hash) |
||||||
|
|
||||||
|
// ReceiptHash is the same-shard transaction receipt trie hash.
|
||||||
|
ReceiptHash() common.Hash |
||||||
|
|
||||||
|
// SetReceiptHash sets the same-shard transaction receipt trie hash.
|
||||||
|
SetReceiptHash(newReceiptHash common.Hash) |
||||||
|
|
||||||
|
// OutgoingReceiptHash is the egress transaction receipt trie hash.
|
||||||
|
OutgoingReceiptHash() common.Hash |
||||||
|
|
||||||
|
// SetOutgoingReceiptHash sets the egress transaction receipt trie hash.
|
||||||
|
SetOutgoingReceiptHash(newOutgoingReceiptHash common.Hash) |
||||||
|
|
||||||
|
// IncomingReceiptHash is the ingress transaction receipt trie hash.
|
||||||
|
IncomingReceiptHash() common.Hash |
||||||
|
|
||||||
|
// SetIncomingReceiptHash sets the ingress transaction receipt trie hash.
|
||||||
|
SetIncomingReceiptHash(newIncomingReceiptHash common.Hash) |
||||||
|
|
||||||
|
// Bloom is the Bloom filter that indexes accounts and topics logged by smart
|
||||||
|
// contract transactions (executions) in this block.
|
||||||
|
Bloom() types.Bloom |
||||||
|
|
||||||
|
// SetBloom sets the smart contract log Bloom filter for this block.
|
||||||
|
SetBloom(newBloom types.Bloom) |
||||||
|
|
||||||
|
// Number is the block number.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
Number() *big.Int |
||||||
|
|
||||||
|
// SetNumber sets the block number.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
SetNumber(newNumber *big.Int) |
||||||
|
|
||||||
|
// GasLimit is the gas limit for transactions in this block.
|
||||||
|
GasLimit() uint64 |
||||||
|
|
||||||
|
// SetGasLimit sets the gas limit for transactions in this block.
|
||||||
|
SetGasLimit(newGasLimit uint64) |
||||||
|
|
||||||
|
// GasUsed is the amount of gas used by transactions in this block.
|
||||||
|
GasUsed() uint64 |
||||||
|
|
||||||
|
// SetGasUsed sets the amount of gas used by transactions in this block.
|
||||||
|
SetGasUsed(newGasUsed uint64) |
||||||
|
|
||||||
|
// Time is the UNIX timestamp of this block.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
Time() *big.Int |
||||||
|
|
||||||
|
// SetTime sets the UNIX timestamp of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
SetTime(newTime *big.Int) |
||||||
|
|
||||||
|
// Extra is the extra data field of this block.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
Extra() []byte |
||||||
|
|
||||||
|
// SetExtra sets the extra data field of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
SetExtra(newExtra []byte) |
||||||
|
|
||||||
|
// MixDigest is the mixhash.
|
||||||
|
//
|
||||||
|
// This field is a remnant from Ethereum, and Harmony does not use it and always
|
||||||
|
// zeroes it out.
|
||||||
|
MixDigest() common.Hash |
||||||
|
|
||||||
|
// SetMixDigest sets the mixhash of this block.
|
||||||
|
SetMixDigest(newMixDigest common.Hash) |
||||||
|
|
||||||
|
// ViewID is the ID of the view in which this block was originally proposed.
|
||||||
|
//
|
||||||
|
// It normally increases by one for each subsequent block, or by more than one
|
||||||
|
// if one or more PBFT/FBFT view changes have occurred.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
ViewID() *big.Int |
||||||
|
|
||||||
|
// SetViewID sets the view ID in which the block was originally proposed.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
SetViewID(newViewID *big.Int) |
||||||
|
|
||||||
|
// Epoch is the epoch number of this block.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
Epoch() *big.Int |
||||||
|
|
||||||
|
// SetEpoch sets the epoch number of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
SetEpoch(newEpoch *big.Int) |
||||||
|
|
||||||
|
// ShardID is the shard ID to which this block belongs.
|
||||||
|
ShardID() uint32 |
||||||
|
|
||||||
|
// SetShardID sets the shard ID to which this block belongs.
|
||||||
|
SetShardID(newShardID uint32) |
||||||
|
|
||||||
|
// LastCommitSignature is the FBFT commit group signature for the last block.
|
||||||
|
LastCommitSignature() [96]byte |
||||||
|
|
||||||
|
// SetLastCommitSignature sets the FBFT commit group signature for the last
|
||||||
|
// block.
|
||||||
|
SetLastCommitSignature(newLastCommitSignature [96]byte) |
||||||
|
|
||||||
|
// LastCommitBitmap is the signatory bitmap of the previous block. Bit
|
||||||
|
// positions index into committee member array.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
LastCommitBitmap() []byte |
||||||
|
|
||||||
|
// SetLastCommitBitmap sets the signatory bitmap of the previous block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
SetLastCommitBitmap(newLastCommitBitmap []byte) |
||||||
|
|
||||||
|
// ShardStateHash is the shard state hash.
|
||||||
|
ShardStateHash() common.Hash |
||||||
|
|
||||||
|
// SetShardStateHash sets the shard state hash.
|
||||||
|
SetShardStateHash(newShardStateHash common.Hash) |
||||||
|
|
||||||
|
// Vrf is the output of the VRF for the epoch.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
Vrf() []byte |
||||||
|
|
||||||
|
// SetVrf sets the output of the VRF for the epoch.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
SetVrf(newVrf []byte) |
||||||
|
|
||||||
|
// Vdf is the output of the VDF for the epoch.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
Vdf() []byte |
||||||
|
|
||||||
|
// SetVdf sets the output of the VDF for the epoch.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
SetVdf(newVdf []byte) |
||||||
|
|
||||||
|
// ShardState is the RLP-encoded form of shard state (list of committees) for
|
||||||
|
// the next epoch.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
ShardState() []byte |
||||||
|
|
||||||
|
// SetShardState sets the RLP-encoded form of shard state
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
SetShardState(newShardState []byte) |
||||||
|
|
||||||
|
// CrossLinks is the RLP-encoded form of non-beacon block headers chosen to be
|
||||||
|
// canonical by the beacon committee. This field is present only on beacon
|
||||||
|
// chain block headers.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
CrossLinks() []byte |
||||||
|
|
||||||
|
// SetCrossLinks sets the RLP-encoded form of non-beacon block headers chosen to
|
||||||
|
// be canonical by the beacon committee.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
SetCrossLinks(newCrossLinks []byte) |
||||||
|
|
||||||
|
// Hash returns the block hash of the header, which is simply the legacy
|
||||||
|
// Keccak256 hash of its RLP encoding.
|
||||||
|
Hash() common.Hash |
||||||
|
|
||||||
|
// Size returns the approximate memory used by all internal contents. It is
|
||||||
|
// used to approximate and limit the memory consumption of various caches.
|
||||||
|
Size() common.StorageSize |
||||||
|
|
||||||
|
// Logger returns a sub-logger with block contexts added.
|
||||||
|
Logger(logger *zerolog.Logger) *zerolog.Logger |
||||||
|
|
||||||
|
// GetShardState returns the deserialized shard state object.
|
||||||
|
GetShardState() (shard.State, error) |
||||||
|
|
||||||
|
// Copy returns a copy of the header.
|
||||||
|
Copy() Header |
||||||
|
} |
@ -1,6 +1,6 @@ |
|||||||
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
|
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
|
||||||
|
|
||||||
package block |
package v0 |
||||||
|
|
||||||
import ( |
import ( |
||||||
"encoding/json" |
"encoding/json" |
@ -0,0 +1,433 @@ |
|||||||
|
package v0 |
||||||
|
|
||||||
|
import ( |
||||||
|
"io" |
||||||
|
"math/big" |
||||||
|
"unsafe" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil" |
||||||
|
ethtypes "github.com/ethereum/go-ethereum/core/types" |
||||||
|
"github.com/ethereum/go-ethereum/rlp" |
||||||
|
"github.com/rs/zerolog" |
||||||
|
|
||||||
|
blockif "github.com/harmony-one/harmony/block/interface" |
||||||
|
"github.com/harmony-one/harmony/crypto/hash" |
||||||
|
"github.com/harmony-one/harmony/internal/utils" |
||||||
|
"github.com/harmony-one/harmony/shard" |
||||||
|
) |
||||||
|
|
||||||
|
// Header is the V1 block header.
|
||||||
|
type Header struct { |
||||||
|
fields headerFields |
||||||
|
} |
||||||
|
|
||||||
|
// EncodeRLP encodes the header fields into RLP format.
|
||||||
|
func (h *Header) EncodeRLP(w io.Writer) error { |
||||||
|
return rlp.Encode(w, &h.fields) |
||||||
|
} |
||||||
|
|
||||||
|
// DecodeRLP decodes the given RLP decode stream into the header fields.
|
||||||
|
func (h *Header) DecodeRLP(s *rlp.Stream) error { |
||||||
|
return s.Decode(&h.fields) |
||||||
|
} |
||||||
|
|
||||||
|
// NewHeader creates a new header object.
|
||||||
|
func NewHeader() *Header { |
||||||
|
return &Header{headerFields{ |
||||||
|
Number: new(big.Int), |
||||||
|
Time: new(big.Int), |
||||||
|
ViewID: new(big.Int), |
||||||
|
Epoch: new(big.Int), |
||||||
|
}} |
||||||
|
} |
||||||
|
|
||||||
|
type headerFields struct { |
||||||
|
ParentHash common.Hash `json:"parentHash" gencodec:"required"` |
||||||
|
Coinbase common.Address `json:"miner" gencodec:"required"` |
||||||
|
Root common.Hash `json:"stateRoot" gencodec:"required"` |
||||||
|
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` |
||||||
|
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` |
||||||
|
Bloom ethtypes.Bloom `json:"logsBloom" gencodec:"required"` |
||||||
|
Number *big.Int `json:"number" gencodec:"required"` |
||||||
|
GasLimit uint64 `json:"gasLimit" gencodec:"required"` |
||||||
|
GasUsed uint64 `json:"gasUsed" gencodec:"required"` |
||||||
|
Time *big.Int `json:"timestamp" gencodec:"required"` |
||||||
|
Extra []byte `json:"extraData" gencodec:"required"` |
||||||
|
MixDigest common.Hash `json:"mixHash" gencodec:"required"` |
||||||
|
// Additional Fields
|
||||||
|
ViewID *big.Int `json:"viewID" gencodec:"required"` |
||||||
|
Epoch *big.Int `json:"epoch" gencodec:"required"` |
||||||
|
ShardID uint32 `json:"shardID" gencodec:"required"` |
||||||
|
LastCommitSignature [96]byte `json:"lastCommitSignature" gencodec:"required"` |
||||||
|
LastCommitBitmap []byte `json:"lastCommitBitmap" gencodec:"required"` // Contains which validator signed
|
||||||
|
ShardStateHash common.Hash `json:"shardStateRoot"` |
||||||
|
ShardState []byte `json:"shardState"` |
||||||
|
} |
||||||
|
|
||||||
|
// ParentHash is the header hash of the parent block. For the genesis block
|
||||||
|
// which has no parent by definition, this field is zeroed out.
|
||||||
|
func (h *Header) ParentHash() common.Hash { |
||||||
|
return h.fields.ParentHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetParentHash sets the parent hash field.
|
||||||
|
func (h *Header) SetParentHash(newParentHash common.Hash) { |
||||||
|
h.fields.ParentHash = newParentHash |
||||||
|
} |
||||||
|
|
||||||
|
// Coinbase is the address of the node that proposed this block and all
|
||||||
|
// transactions in it.
|
||||||
|
func (h *Header) Coinbase() common.Address { |
||||||
|
return h.fields.Coinbase |
||||||
|
} |
||||||
|
|
||||||
|
// SetCoinbase sets the coinbase address field.
|
||||||
|
func (h *Header) SetCoinbase(newCoinbase common.Address) { |
||||||
|
h.fields.Coinbase = newCoinbase |
||||||
|
} |
||||||
|
|
||||||
|
// Root is the state (account) trie root hash.
|
||||||
|
func (h *Header) Root() common.Hash { |
||||||
|
return h.fields.Root |
||||||
|
} |
||||||
|
|
||||||
|
// SetRoot sets the state trie root hash field.
|
||||||
|
func (h *Header) SetRoot(newRoot common.Hash) { |
||||||
|
h.fields.Root = newRoot |
||||||
|
} |
||||||
|
|
||||||
|
// TxHash is the transaction trie root hash.
|
||||||
|
func (h *Header) TxHash() common.Hash { |
||||||
|
return h.fields.TxHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetTxHash sets the transaction trie root hash field.
|
||||||
|
func (h *Header) SetTxHash(newTxHash common.Hash) { |
||||||
|
h.fields.TxHash = newTxHash |
||||||
|
} |
||||||
|
|
||||||
|
// ReceiptHash is the same-shard transaction receipt trie hash.
|
||||||
|
func (h *Header) ReceiptHash() common.Hash { |
||||||
|
return h.fields.ReceiptHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetReceiptHash sets the same-shard transaction receipt trie hash.
|
||||||
|
func (h *Header) SetReceiptHash(newReceiptHash common.Hash) { |
||||||
|
h.fields.ReceiptHash = newReceiptHash |
||||||
|
} |
||||||
|
|
||||||
|
// OutgoingReceiptHash is the egress transaction receipt trie hash.
|
||||||
|
func (h *Header) OutgoingReceiptHash() common.Hash { |
||||||
|
return ethtypes.EmptyRootHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetOutgoingReceiptHash sets the egress transaction receipt trie hash.
|
||||||
|
func (h *Header) SetOutgoingReceiptHash(newOutgoingReceiptHash common.Hash) { |
||||||
|
if newOutgoingReceiptHash != ethtypes.EmptyRootHash { |
||||||
|
h.Logger(utils.Logger()).Warn(). |
||||||
|
Hex("outgoingReceiptHash", newOutgoingReceiptHash[:]). |
||||||
|
Msg("non-empty outgoing receipt root hash provided but cannot be stored") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// IncomingReceiptHash is the ingress transaction receipt trie hash.
|
||||||
|
func (h *Header) IncomingReceiptHash() common.Hash { |
||||||
|
return ethtypes.EmptyRootHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetIncomingReceiptHash sets the ingress transaction receipt trie hash.
|
||||||
|
func (h *Header) SetIncomingReceiptHash(newIncomingReceiptHash common.Hash) { |
||||||
|
if newIncomingReceiptHash != ethtypes.EmptyRootHash { |
||||||
|
h.Logger(utils.Logger()).Warn(). |
||||||
|
Hex("incomingReceiptHash", newIncomingReceiptHash[:]). |
||||||
|
Msg("non-empty outgoing receipt root hash provided but cannot be stored") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Bloom is the Bloom filter that indexes accounts and topics logged by smart
|
||||||
|
// contract transactions (executions) in this block.
|
||||||
|
func (h *Header) Bloom() ethtypes.Bloom { |
||||||
|
return h.fields.Bloom |
||||||
|
} |
||||||
|
|
||||||
|
// SetBloom sets the smart contract log Bloom filter for this block.
|
||||||
|
func (h *Header) SetBloom(newBloom ethtypes.Bloom) { |
||||||
|
h.fields.Bloom = newBloom |
||||||
|
} |
||||||
|
|
||||||
|
// Number is the block number.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Number() *big.Int { |
||||||
|
return new(big.Int).Set(h.fields.Number) |
||||||
|
} |
||||||
|
|
||||||
|
// SetNumber sets the block number.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetNumber(newNumber *big.Int) { |
||||||
|
h.fields.Number = new(big.Int).Set(newNumber) |
||||||
|
} |
||||||
|
|
||||||
|
// GasLimit is the gas limit for transactions in this block.
|
||||||
|
func (h *Header) GasLimit() uint64 { |
||||||
|
return h.fields.GasLimit |
||||||
|
} |
||||||
|
|
||||||
|
// SetGasLimit sets the gas limit for transactions in this block.
|
||||||
|
func (h *Header) SetGasLimit(newGasLimit uint64) { |
||||||
|
h.fields.GasLimit = newGasLimit |
||||||
|
} |
||||||
|
|
||||||
|
// GasUsed is the amount of gas used by transactions in this block.
|
||||||
|
func (h *Header) GasUsed() uint64 { |
||||||
|
return h.fields.GasUsed |
||||||
|
} |
||||||
|
|
||||||
|
// SetGasUsed sets the amount of gas used by transactions in this block.
|
||||||
|
func (h *Header) SetGasUsed(newGasUsed uint64) { |
||||||
|
h.fields.GasUsed = newGasUsed |
||||||
|
} |
||||||
|
|
||||||
|
// Time is the UNIX timestamp of this block.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Time() *big.Int { |
||||||
|
return new(big.Int).Set(h.fields.Time) |
||||||
|
} |
||||||
|
|
||||||
|
// SetTime sets the UNIX timestamp of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetTime(newTime *big.Int) { |
||||||
|
h.fields.Time = new(big.Int).Set(newTime) |
||||||
|
} |
||||||
|
|
||||||
|
// Extra is the extra data field of this block.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Extra() []byte { |
||||||
|
return append(h.fields.Extra[:0:0], h.fields.Extra...) |
||||||
|
} |
||||||
|
|
||||||
|
// SetExtra sets the extra data field of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetExtra(newExtra []byte) { |
||||||
|
h.fields.Extra = append(newExtra[:0:0], newExtra...) |
||||||
|
} |
||||||
|
|
||||||
|
// MixDigest is the mixhash.
|
||||||
|
//
|
||||||
|
// This field is a remnant from Ethereum, and Harmony does not use it and always
|
||||||
|
// zeroes it out.
|
||||||
|
func (h *Header) MixDigest() common.Hash { |
||||||
|
return h.fields.MixDigest |
||||||
|
} |
||||||
|
|
||||||
|
// SetMixDigest sets the mixhash of this block.
|
||||||
|
func (h *Header) SetMixDigest(newMixDigest common.Hash) { |
||||||
|
h.fields.MixDigest = newMixDigest |
||||||
|
} |
||||||
|
|
||||||
|
// ViewID is the ID of the view in which this block was originally proposed.
|
||||||
|
//
|
||||||
|
// It normally increases by one for each subsequent block, or by more than one
|
||||||
|
// if one or more PBFT/FBFT view changes have occurred.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) ViewID() *big.Int { |
||||||
|
return new(big.Int).Set(h.fields.ViewID) |
||||||
|
} |
||||||
|
|
||||||
|
// SetViewID sets the view ID in which the block was originally proposed.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetViewID(newViewID *big.Int) { |
||||||
|
h.fields.ViewID = new(big.Int).Set(newViewID) |
||||||
|
} |
||||||
|
|
||||||
|
// Epoch is the epoch number of this block.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Epoch() *big.Int { |
||||||
|
return new(big.Int).Set(h.fields.Epoch) |
||||||
|
} |
||||||
|
|
||||||
|
// SetEpoch sets the epoch number of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetEpoch(newEpoch *big.Int) { |
||||||
|
h.fields.Epoch = new(big.Int).Set(newEpoch) |
||||||
|
} |
||||||
|
|
||||||
|
// ShardID is the shard ID to which this block belongs.
|
||||||
|
func (h *Header) ShardID() uint32 { |
||||||
|
return h.fields.ShardID |
||||||
|
} |
||||||
|
|
||||||
|
// SetShardID sets the shard ID to which this block belongs.
|
||||||
|
func (h *Header) SetShardID(newShardID uint32) { |
||||||
|
h.fields.ShardID = newShardID |
||||||
|
} |
||||||
|
|
||||||
|
// LastCommitSignature is the FBFT commit group signature for the last block.
|
||||||
|
func (h *Header) LastCommitSignature() [96]byte { |
||||||
|
return h.fields.LastCommitSignature |
||||||
|
} |
||||||
|
|
||||||
|
// SetLastCommitSignature sets the FBFT commit group signature for the last
|
||||||
|
// block.
|
||||||
|
func (h *Header) SetLastCommitSignature(newLastCommitSignature [96]byte) { |
||||||
|
h.fields.LastCommitSignature = newLastCommitSignature |
||||||
|
} |
||||||
|
|
||||||
|
// LastCommitBitmap is the signatory bitmap of the previous block. Bit
|
||||||
|
// positions index into committee member array.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) LastCommitBitmap() []byte { |
||||||
|
return append(h.fields.LastCommitBitmap[:0:0], h.fields.LastCommitBitmap...) |
||||||
|
} |
||||||
|
|
||||||
|
// SetLastCommitBitmap sets the signatory bitmap of the previous block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetLastCommitBitmap(newLastCommitBitmap []byte) { |
||||||
|
h.fields.LastCommitBitmap = append(newLastCommitBitmap[:0:0], newLastCommitBitmap...) |
||||||
|
} |
||||||
|
|
||||||
|
// ShardStateHash is the shard state hash.
|
||||||
|
func (h *Header) ShardStateHash() common.Hash { |
||||||
|
return h.fields.ShardStateHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetShardStateHash sets the shard state hash.
|
||||||
|
func (h *Header) SetShardStateHash(newShardStateHash common.Hash) { |
||||||
|
h.fields.ShardStateHash = newShardStateHash |
||||||
|
} |
||||||
|
|
||||||
|
// Vrf is the output of the VRF for the epoch.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Vrf() []byte { |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// SetVrf sets the output of the VRF for the epoch.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetVrf(newVrf []byte) { |
||||||
|
if len(newVrf) > 0 { |
||||||
|
h.Logger(utils.Logger()).Warn(). |
||||||
|
Hex("vrf", newVrf). |
||||||
|
Msg("non-empty VRF provided but cannot be stored") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Vdf is the output of the VDF for the epoch.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Vdf() []byte { |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// SetVdf sets the output of the VDF for the epoch.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetVdf(newVdf []byte) { |
||||||
|
if len(newVdf) > 0 { |
||||||
|
h.Logger(utils.Logger()).Warn(). |
||||||
|
Hex("vdf", newVdf). |
||||||
|
Msg("non-empty VDF provided but cannot be stored") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// ShardState is the RLP-encoded form of shard state (list of committees) for
|
||||||
|
// the next epoch.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) ShardState() []byte { |
||||||
|
return append(h.fields.ShardState[:0:0], h.fields.ShardState...) |
||||||
|
} |
||||||
|
|
||||||
|
// SetShardState sets the RLP-encoded form of shard state
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetShardState(newShardState []byte) { |
||||||
|
h.fields.ShardState = append(newShardState[:0:0], newShardState...) |
||||||
|
} |
||||||
|
|
||||||
|
// CrossLinks is the RLP-encoded form of non-beacon block headers chosen to be
|
||||||
|
// canonical by the beacon committee. This field is present only on beacon
|
||||||
|
// chain block headers.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) CrossLinks() []byte { |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// SetCrossLinks sets the RLP-encoded form of non-beacon block headers chosen to
|
||||||
|
// be canonical by the beacon committee.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetCrossLinks(newCrossLinks []byte) { |
||||||
|
if len(newCrossLinks) > 0 { |
||||||
|
h.Logger(utils.Logger()).Warn(). |
||||||
|
Hex("crossLinks", newCrossLinks). |
||||||
|
Msg("non-empty cross-chain links provided but cannot be stored") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// field type overrides for gencodec
|
||||||
|
type headerMarshaling struct { |
||||||
|
Difficulty *hexutil.Big |
||||||
|
Number *hexutil.Big |
||||||
|
GasLimit hexutil.Uint64 |
||||||
|
GasUsed hexutil.Uint64 |
||||||
|
Time *hexutil.Big |
||||||
|
Extra hexutil.Bytes |
||||||
|
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
|
||||||
|
} |
||||||
|
|
||||||
|
// Hash returns the block hash of the header, which is simply the keccak256 hash of its
|
||||||
|
// RLP encoding.
|
||||||
|
func (h *Header) Hash() common.Hash { |
||||||
|
return hash.FromRLP(h) |
||||||
|
} |
||||||
|
|
||||||
|
// Size returns the approximate memory used by all internal contents. It is used
|
||||||
|
// to approximate and limit the memory consumption of various caches.
|
||||||
|
func (h *Header) Size() common.StorageSize { |
||||||
|
// TODO: update with new fields
|
||||||
|
return common.StorageSize(unsafe.Sizeof(*h)) + common.StorageSize(len(h.Extra())+(h.Number().BitLen()+h.Time().BitLen())/8) |
||||||
|
} |
||||||
|
|
||||||
|
// Logger returns a sub-logger with block contexts added.
|
||||||
|
func (h *Header) Logger(logger *zerolog.Logger) *zerolog.Logger { |
||||||
|
nlogger := logger. |
||||||
|
With(). |
||||||
|
Str("blockHash", h.Hash().Hex()). |
||||||
|
Uint32("blockShard", h.ShardID()). |
||||||
|
Uint64("blockEpoch", h.Epoch().Uint64()). |
||||||
|
Uint64("blockNumber", h.Number().Uint64()). |
||||||
|
Logger() |
||||||
|
return &nlogger |
||||||
|
} |
||||||
|
|
||||||
|
// GetShardState returns the deserialized shard state object.
|
||||||
|
func (h *Header) GetShardState() (shard.State, error) { |
||||||
|
shardState := shard.State{} |
||||||
|
err := rlp.DecodeBytes(h.ShardState(), &shardState) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return shardState, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Copy returns a copy of the given header.
|
||||||
|
func (h *Header) Copy() blockif.Header { |
||||||
|
cpy := *h |
||||||
|
return &cpy |
||||||
|
} |
@ -0,0 +1,117 @@ |
|||||||
|
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1 |
||||||
|
|
||||||
|
import ( |
||||||
|
"encoding/json" |
||||||
|
"errors" |
||||||
|
"math/big" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil" |
||||||
|
ethtypes "github.com/ethereum/go-ethereum/core/types" |
||||||
|
) |
||||||
|
|
||||||
|
var _ = (*headerMarshaling)(nil) |
||||||
|
|
||||||
|
func (h Header) MarshalJSON() ([]byte, error) { |
||||||
|
// TODO: update with new fields
|
||||||
|
type Header struct { |
||||||
|
ParentHash common.Hash `json:"parentHash" gencodec:"required"` |
||||||
|
Coinbase common.Address `json:"miner" gencodec:"required"` |
||||||
|
Root common.Hash `json:"stateRoot" gencodec:"required"` |
||||||
|
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` |
||||||
|
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` |
||||||
|
Bloom ethtypes.Bloom `json:"logsBloom" gencodec:"required"` |
||||||
|
Number *hexutil.Big `json:"number" gencodec:"required"` |
||||||
|
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` |
||||||
|
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` |
||||||
|
Time *hexutil.Big `json:"timestamp" gencodec:"required"` |
||||||
|
Extra hexutil.Bytes `json:"extraData" gencodec:"required"` |
||||||
|
MixDigest common.Hash `json:"mixHash" gencodec:"required"` |
||||||
|
Hash common.Hash `json:"hash"` |
||||||
|
} |
||||||
|
var enc Header |
||||||
|
enc.ParentHash = h.ParentHash() |
||||||
|
enc.Coinbase = h.Coinbase() |
||||||
|
enc.Root = h.Root() |
||||||
|
enc.TxHash = h.TxHash() |
||||||
|
enc.ReceiptHash = h.ReceiptHash() |
||||||
|
enc.Bloom = h.Bloom() |
||||||
|
enc.Number = (*hexutil.Big)(h.Number()) |
||||||
|
enc.GasLimit = hexutil.Uint64(h.GasLimit()) |
||||||
|
enc.GasUsed = hexutil.Uint64(h.GasUsed()) |
||||||
|
enc.Time = (*hexutil.Big)(h.Time()) |
||||||
|
enc.Extra = h.Extra() |
||||||
|
enc.MixDigest = h.MixDigest() |
||||||
|
enc.Hash = h.Hash() |
||||||
|
return json.Marshal(&enc) |
||||||
|
} |
||||||
|
|
||||||
|
func (h *Header) UnmarshalJSON(input []byte) error { |
||||||
|
// TODO: update with new fields
|
||||||
|
type Header struct { |
||||||
|
ParentHash *common.Hash `json:"parentHash" gencodec:"required"` |
||||||
|
Coinbase *common.Address `json:"miner" gencodec:"required"` |
||||||
|
Root *common.Hash `json:"stateRoot" gencodec:"required"` |
||||||
|
TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` |
||||||
|
ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` |
||||||
|
Bloom *ethtypes.Bloom `json:"logsBloom" gencodec:"required"` |
||||||
|
Number *hexutil.Big `json:"number" gencodec:"required"` |
||||||
|
GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` |
||||||
|
GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` |
||||||
|
Time *hexutil.Big `json:"timestamp" gencodec:"required"` |
||||||
|
Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` |
||||||
|
MixDigest *common.Hash `json:"mixHash" gencodec:"required"` |
||||||
|
} |
||||||
|
var dec Header |
||||||
|
if err := json.Unmarshal(input, &dec); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
if dec.ParentHash == nil { |
||||||
|
return errors.New("missing required field 'parentHash' for Header") |
||||||
|
} |
||||||
|
h.SetParentHash(*dec.ParentHash) |
||||||
|
if dec.Coinbase == nil { |
||||||
|
return errors.New("missing required field 'miner' for Header") |
||||||
|
} |
||||||
|
h.SetCoinbase(*dec.Coinbase) |
||||||
|
if dec.Root == nil { |
||||||
|
return errors.New("missing required field 'stateRoot' for Header") |
||||||
|
} |
||||||
|
h.SetRoot(*dec.Root) |
||||||
|
if dec.TxHash == nil { |
||||||
|
return errors.New("missing required field 'transactionsRoot' for Header") |
||||||
|
} |
||||||
|
h.SetTxHash(*dec.TxHash) |
||||||
|
if dec.ReceiptHash == nil { |
||||||
|
return errors.New("missing required field 'receiptsRoot' for Header") |
||||||
|
} |
||||||
|
h.SetReceiptHash(*dec.ReceiptHash) |
||||||
|
if dec.Bloom == nil { |
||||||
|
return errors.New("missing required field 'logsBloom' for Header") |
||||||
|
} |
||||||
|
h.SetBloom(*dec.Bloom) |
||||||
|
h.SetNumber((*big.Int)(dec.Number)) |
||||||
|
if dec.GasLimit == nil { |
||||||
|
return errors.New("missing required field 'gasLimit' for Header") |
||||||
|
} |
||||||
|
h.SetGasLimit(uint64(*dec.GasLimit)) |
||||||
|
if dec.GasUsed == nil { |
||||||
|
return errors.New("missing required field 'gasUsed' for Header") |
||||||
|
} |
||||||
|
h.SetGasUsed(uint64(*dec.GasUsed)) |
||||||
|
if dec.Time == nil { |
||||||
|
return errors.New("missing required field 'timestamp' for Header") |
||||||
|
} |
||||||
|
h.SetTime((*big.Int)(dec.Time)) |
||||||
|
if dec.Extra == nil { |
||||||
|
return errors.New("missing required field 'extraData' for Header") |
||||||
|
} |
||||||
|
h.SetExtra(*dec.Extra) |
||||||
|
if dec.MixDigest == nil { |
||||||
|
return errors.New("missing required field 'mixHash' for Header") |
||||||
|
} |
||||||
|
h.SetMixDigest(*dec.MixDigest) |
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,417 @@ |
|||||||
|
package v1 |
||||||
|
|
||||||
|
import ( |
||||||
|
"io" |
||||||
|
"math/big" |
||||||
|
"unsafe" |
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common" |
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil" |
||||||
|
ethtypes "github.com/ethereum/go-ethereum/core/types" |
||||||
|
"github.com/ethereum/go-ethereum/rlp" |
||||||
|
"github.com/rs/zerolog" |
||||||
|
|
||||||
|
blockif "github.com/harmony-one/harmony/block/interface" |
||||||
|
"github.com/harmony-one/harmony/crypto/hash" |
||||||
|
"github.com/harmony-one/harmony/shard" |
||||||
|
) |
||||||
|
|
||||||
|
// Header is the V1 block header.
|
||||||
|
type Header struct { |
||||||
|
fields headerFields |
||||||
|
} |
||||||
|
|
||||||
|
// EncodeRLP encodes the header fields into RLP format.
|
||||||
|
func (h *Header) EncodeRLP(w io.Writer) error { |
||||||
|
return rlp.Encode(w, &h.fields) |
||||||
|
} |
||||||
|
|
||||||
|
// DecodeRLP decodes the given RLP decode stream into the header fields.
|
||||||
|
func (h *Header) DecodeRLP(s *rlp.Stream) error { |
||||||
|
return s.Decode(&h.fields) |
||||||
|
} |
||||||
|
|
||||||
|
// NewHeader creates a new header object.
|
||||||
|
func NewHeader() *Header { |
||||||
|
return &Header{headerFields{ |
||||||
|
Number: new(big.Int), |
||||||
|
Time: new(big.Int), |
||||||
|
ViewID: new(big.Int), |
||||||
|
Epoch: new(big.Int), |
||||||
|
}} |
||||||
|
} |
||||||
|
|
||||||
|
type headerFields struct { |
||||||
|
ParentHash common.Hash `json:"parentHash" gencodec:"required"` |
||||||
|
Coinbase common.Address `json:"miner" gencodec:"required"` |
||||||
|
Root common.Hash `json:"stateRoot" gencodec:"required"` |
||||||
|
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` |
||||||
|
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` |
||||||
|
OutgoingReceiptHash common.Hash `json:"outgoingReceiptsRoot" gencodec:"required"` |
||||||
|
IncomingReceiptHash common.Hash `json:"incomingReceiptsRoot" gencodec:"required"` |
||||||
|
Bloom ethtypes.Bloom `json:"logsBloom" gencodec:"required"` |
||||||
|
Number *big.Int `json:"number" gencodec:"required"` |
||||||
|
GasLimit uint64 `json:"gasLimit" gencodec:"required"` |
||||||
|
GasUsed uint64 `json:"gasUsed" gencodec:"required"` |
||||||
|
Time *big.Int `json:"timestamp" gencodec:"required"` |
||||||
|
Extra []byte `json:"extraData" gencodec:"required"` |
||||||
|
MixDigest common.Hash `json:"mixHash" gencodec:"required"` |
||||||
|
// Additional Fields
|
||||||
|
ViewID *big.Int `json:"viewID" gencodec:"required"` |
||||||
|
Epoch *big.Int `json:"epoch" gencodec:"required"` |
||||||
|
ShardID uint32 `json:"shardID" gencodec:"required"` |
||||||
|
LastCommitSignature [96]byte `json:"lastCommitSignature" gencodec:"required"` |
||||||
|
LastCommitBitmap []byte `json:"lastCommitBitmap" gencodec:"required"` // Contains which validator signed
|
||||||
|
ShardStateHash common.Hash `json:"shardStateRoot"` |
||||||
|
Vrf []byte `json:"vrf"` |
||||||
|
Vdf []byte `json:"vdf"` |
||||||
|
ShardState []byte `json:"shardState"` |
||||||
|
CrossLinks []byte `json:"crossLink"` |
||||||
|
} |
||||||
|
|
||||||
|
// ParentHash is the header hash of the parent block. For the genesis block
|
||||||
|
// which has no parent by definition, this field is zeroed out.
|
||||||
|
func (h *Header) ParentHash() common.Hash { |
||||||
|
return h.fields.ParentHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetParentHash sets the parent hash field.
|
||||||
|
func (h *Header) SetParentHash(newParentHash common.Hash) { |
||||||
|
h.fields.ParentHash = newParentHash |
||||||
|
} |
||||||
|
|
||||||
|
// Coinbase is the address of the node that proposed this block and all
|
||||||
|
// transactions in it.
|
||||||
|
func (h *Header) Coinbase() common.Address { |
||||||
|
return h.fields.Coinbase |
||||||
|
} |
||||||
|
|
||||||
|
// SetCoinbase sets the coinbase address field.
|
||||||
|
func (h *Header) SetCoinbase(newCoinbase common.Address) { |
||||||
|
h.fields.Coinbase = newCoinbase |
||||||
|
} |
||||||
|
|
||||||
|
// Root is the state (account) trie root hash.
|
||||||
|
func (h *Header) Root() common.Hash { |
||||||
|
return h.fields.Root |
||||||
|
} |
||||||
|
|
||||||
|
// SetRoot sets the state trie root hash field.
|
||||||
|
func (h *Header) SetRoot(newRoot common.Hash) { |
||||||
|
h.fields.Root = newRoot |
||||||
|
} |
||||||
|
|
||||||
|
// TxHash is the transaction trie root hash.
|
||||||
|
func (h *Header) TxHash() common.Hash { |
||||||
|
return h.fields.TxHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetTxHash sets the transaction trie root hash field.
|
||||||
|
func (h *Header) SetTxHash(newTxHash common.Hash) { |
||||||
|
h.fields.TxHash = newTxHash |
||||||
|
} |
||||||
|
|
||||||
|
// ReceiptHash is the same-shard transaction receipt trie hash.
|
||||||
|
func (h *Header) ReceiptHash() common.Hash { |
||||||
|
return h.fields.ReceiptHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetReceiptHash sets the same-shard transaction receipt trie hash.
|
||||||
|
func (h *Header) SetReceiptHash(newReceiptHash common.Hash) { |
||||||
|
h.fields.ReceiptHash = newReceiptHash |
||||||
|
} |
||||||
|
|
||||||
|
// OutgoingReceiptHash is the egress transaction receipt trie hash.
|
||||||
|
func (h *Header) OutgoingReceiptHash() common.Hash { |
||||||
|
return h.fields.OutgoingReceiptHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetOutgoingReceiptHash sets the egress transaction receipt trie hash.
|
||||||
|
func (h *Header) SetOutgoingReceiptHash(newOutgoingReceiptHash common.Hash) { |
||||||
|
h.fields.OutgoingReceiptHash = newOutgoingReceiptHash |
||||||
|
} |
||||||
|
|
||||||
|
// IncomingReceiptHash is the ingress transaction receipt trie hash.
|
||||||
|
func (h *Header) IncomingReceiptHash() common.Hash { |
||||||
|
return h.fields.IncomingReceiptHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetIncomingReceiptHash sets the ingress transaction receipt trie hash.
|
||||||
|
func (h *Header) SetIncomingReceiptHash(newIncomingReceiptHash common.Hash) { |
||||||
|
h.fields.IncomingReceiptHash = newIncomingReceiptHash |
||||||
|
} |
||||||
|
|
||||||
|
// Bloom is the Bloom filter that indexes accounts and topics logged by smart
|
||||||
|
// contract transactions (executions) in this block.
|
||||||
|
func (h *Header) Bloom() ethtypes.Bloom { |
||||||
|
return h.fields.Bloom |
||||||
|
} |
||||||
|
|
||||||
|
// SetBloom sets the smart contract log Bloom filter for this block.
|
||||||
|
func (h *Header) SetBloom(newBloom ethtypes.Bloom) { |
||||||
|
h.fields.Bloom = newBloom |
||||||
|
} |
||||||
|
|
||||||
|
// Number is the block number.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Number() *big.Int { |
||||||
|
return new(big.Int).Set(h.fields.Number) |
||||||
|
} |
||||||
|
|
||||||
|
// SetNumber sets the block number.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetNumber(newNumber *big.Int) { |
||||||
|
h.fields.Number = new(big.Int).Set(newNumber) |
||||||
|
} |
||||||
|
|
||||||
|
// GasLimit is the gas limit for transactions in this block.
|
||||||
|
func (h *Header) GasLimit() uint64 { |
||||||
|
return h.fields.GasLimit |
||||||
|
} |
||||||
|
|
||||||
|
// SetGasLimit sets the gas limit for transactions in this block.
|
||||||
|
func (h *Header) SetGasLimit(newGasLimit uint64) { |
||||||
|
h.fields.GasLimit = newGasLimit |
||||||
|
} |
||||||
|
|
||||||
|
// GasUsed is the amount of gas used by transactions in this block.
|
||||||
|
func (h *Header) GasUsed() uint64 { |
||||||
|
return h.fields.GasUsed |
||||||
|
} |
||||||
|
|
||||||
|
// SetGasUsed sets the amount of gas used by transactions in this block.
|
||||||
|
func (h *Header) SetGasUsed(newGasUsed uint64) { |
||||||
|
h.fields.GasUsed = newGasUsed |
||||||
|
} |
||||||
|
|
||||||
|
// Time is the UNIX timestamp of this block.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Time() *big.Int { |
||||||
|
return new(big.Int).Set(h.fields.Time) |
||||||
|
} |
||||||
|
|
||||||
|
// SetTime sets the UNIX timestamp of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetTime(newTime *big.Int) { |
||||||
|
h.fields.Time = new(big.Int).Set(newTime) |
||||||
|
} |
||||||
|
|
||||||
|
// Extra is the extra data field of this block.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Extra() []byte { |
||||||
|
return append(h.fields.Extra[:0:0], h.fields.Extra...) |
||||||
|
} |
||||||
|
|
||||||
|
// SetExtra sets the extra data field of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetExtra(newExtra []byte) { |
||||||
|
h.fields.Extra = append(newExtra[:0:0], newExtra...) |
||||||
|
} |
||||||
|
|
||||||
|
// MixDigest is the mixhash.
|
||||||
|
//
|
||||||
|
// This field is a remnant from Ethereum, and Harmony does not use it and always
|
||||||
|
// zeroes it out.
|
||||||
|
func (h *Header) MixDigest() common.Hash { |
||||||
|
return h.fields.MixDigest |
||||||
|
} |
||||||
|
|
||||||
|
// SetMixDigest sets the mixhash of this block.
|
||||||
|
func (h *Header) SetMixDigest(newMixDigest common.Hash) { |
||||||
|
h.fields.MixDigest = newMixDigest |
||||||
|
} |
||||||
|
|
||||||
|
// ViewID is the ID of the view in which this block was originally proposed.
|
||||||
|
//
|
||||||
|
// It normally increases by one for each subsequent block, or by more than one
|
||||||
|
// if one or more PBFT/FBFT view changes have occurred.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) ViewID() *big.Int { |
||||||
|
return new(big.Int).Set(h.fields.ViewID) |
||||||
|
} |
||||||
|
|
||||||
|
// SetViewID sets the view ID in which the block was originally proposed.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetViewID(newViewID *big.Int) { |
||||||
|
h.fields.ViewID = new(big.Int).Set(newViewID) |
||||||
|
} |
||||||
|
|
||||||
|
// Epoch is the epoch number of this block.
|
||||||
|
//
|
||||||
|
// The returned instance is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Epoch() *big.Int { |
||||||
|
return new(big.Int).Set(h.fields.Epoch) |
||||||
|
} |
||||||
|
|
||||||
|
// SetEpoch sets the epoch number of this block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetEpoch(newEpoch *big.Int) { |
||||||
|
h.fields.Epoch = new(big.Int).Set(newEpoch) |
||||||
|
} |
||||||
|
|
||||||
|
// ShardID is the shard ID to which this block belongs.
|
||||||
|
func (h *Header) ShardID() uint32 { |
||||||
|
return h.fields.ShardID |
||||||
|
} |
||||||
|
|
||||||
|
// SetShardID sets the shard ID to which this block belongs.
|
||||||
|
func (h *Header) SetShardID(newShardID uint32) { |
||||||
|
h.fields.ShardID = newShardID |
||||||
|
} |
||||||
|
|
||||||
|
// LastCommitSignature is the FBFT commit group signature for the last block.
|
||||||
|
func (h *Header) LastCommitSignature() [96]byte { |
||||||
|
return h.fields.LastCommitSignature |
||||||
|
} |
||||||
|
|
||||||
|
// SetLastCommitSignature sets the FBFT commit group signature for the last
|
||||||
|
// block.
|
||||||
|
func (h *Header) SetLastCommitSignature(newLastCommitSignature [96]byte) { |
||||||
|
h.fields.LastCommitSignature = newLastCommitSignature |
||||||
|
} |
||||||
|
|
||||||
|
// LastCommitBitmap is the signatory bitmap of the previous block. Bit
|
||||||
|
// positions index into committee member array.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) LastCommitBitmap() []byte { |
||||||
|
return append(h.fields.LastCommitBitmap[:0:0], h.fields.LastCommitBitmap...) |
||||||
|
} |
||||||
|
|
||||||
|
// SetLastCommitBitmap sets the signatory bitmap of the previous block.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetLastCommitBitmap(newLastCommitBitmap []byte) { |
||||||
|
h.fields.LastCommitBitmap = append(newLastCommitBitmap[:0:0], newLastCommitBitmap...) |
||||||
|
} |
||||||
|
|
||||||
|
// ShardStateHash is the shard state hash.
|
||||||
|
func (h *Header) ShardStateHash() common.Hash { |
||||||
|
return h.fields.ShardStateHash |
||||||
|
} |
||||||
|
|
||||||
|
// SetShardStateHash sets the shard state hash.
|
||||||
|
func (h *Header) SetShardStateHash(newShardStateHash common.Hash) { |
||||||
|
h.fields.ShardStateHash = newShardStateHash |
||||||
|
} |
||||||
|
|
||||||
|
// Vrf is the output of the VRF for the epoch.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Vrf() []byte { |
||||||
|
return append(h.fields.Vrf[:0:0], h.fields.Vrf...) |
||||||
|
} |
||||||
|
|
||||||
|
// SetVrf sets the output of the VRF for the epoch.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetVrf(newVrf []byte) { |
||||||
|
h.fields.Vrf = append(newVrf[:0:0], newVrf...) |
||||||
|
} |
||||||
|
|
||||||
|
// Vdf is the output of the VDF for the epoch.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) Vdf() []byte { |
||||||
|
return append(h.fields.Vdf[:0:0], h.fields.Vdf...) |
||||||
|
} |
||||||
|
|
||||||
|
// SetVdf sets the output of the VDF for the epoch.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetVdf(newVdf []byte) { |
||||||
|
h.fields.Vdf = append(newVdf[:0:0], newVdf...) |
||||||
|
} |
||||||
|
|
||||||
|
// ShardState is the RLP-encoded form of shard state (list of committees) for
|
||||||
|
// the next epoch.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) ShardState() []byte { |
||||||
|
return append(h.fields.ShardState[:0:0], h.fields.ShardState...) |
||||||
|
} |
||||||
|
|
||||||
|
// SetShardState sets the RLP-encoded form of shard state
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetShardState(newShardState []byte) { |
||||||
|
h.fields.ShardState = append(newShardState[:0:0], newShardState...) |
||||||
|
} |
||||||
|
|
||||||
|
// CrossLinks is the RLP-encoded form of non-beacon block headers chosen to be
|
||||||
|
// canonical by the beacon committee. This field is present only on beacon
|
||||||
|
// chain block headers.
|
||||||
|
//
|
||||||
|
// The returned slice is a copy; the caller may do anything with it.
|
||||||
|
func (h *Header) CrossLinks() []byte { |
||||||
|
return append(h.fields.CrossLinks[:0:0], h.fields.CrossLinks...) |
||||||
|
} |
||||||
|
|
||||||
|
// SetCrossLinks sets the RLP-encoded form of non-beacon block headers chosen to
|
||||||
|
// be canonical by the beacon committee.
|
||||||
|
//
|
||||||
|
// It stores a copy; the caller may freely modify the original.
|
||||||
|
func (h *Header) SetCrossLinks(newCrossLinks []byte) { |
||||||
|
h.fields.CrossLinks = append(newCrossLinks[:0:0], newCrossLinks...) |
||||||
|
} |
||||||
|
|
||||||
|
// field type overrides for gencodec
|
||||||
|
type headerMarshaling struct { |
||||||
|
Difficulty *hexutil.Big |
||||||
|
Number *hexutil.Big |
||||||
|
GasLimit hexutil.Uint64 |
||||||
|
GasUsed hexutil.Uint64 |
||||||
|
Time *hexutil.Big |
||||||
|
Extra hexutil.Bytes |
||||||
|
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
|
||||||
|
} |
||||||
|
|
||||||
|
// Hash returns the block hash of the header, which is simply the keccak256 hash of its
|
||||||
|
// RLP encoding.
|
||||||
|
func (h *Header) Hash() common.Hash { |
||||||
|
return hash.FromRLP(h) |
||||||
|
} |
||||||
|
|
||||||
|
// Size returns the approximate memory used by all internal contents. It is used
|
||||||
|
// to approximate and limit the memory consumption of various caches.
|
||||||
|
func (h *Header) Size() common.StorageSize { |
||||||
|
// TODO: update with new fields
|
||||||
|
return common.StorageSize(unsafe.Sizeof(*h)) + common.StorageSize(len(h.Extra())+(h.Number().BitLen()+h.Time().BitLen())/8) |
||||||
|
} |
||||||
|
|
||||||
|
// Logger returns a sub-logger with block contexts added.
|
||||||
|
func (h *Header) Logger(logger *zerolog.Logger) *zerolog.Logger { |
||||||
|
nlogger := logger. |
||||||
|
With(). |
||||||
|
Str("blockHash", h.Hash().Hex()). |
||||||
|
Uint32("blockShard", h.ShardID()). |
||||||
|
Uint64("blockEpoch", h.Epoch().Uint64()). |
||||||
|
Uint64("blockNumber", h.Number().Uint64()). |
||||||
|
Logger() |
||||||
|
return &nlogger |
||||||
|
} |
||||||
|
|
||||||
|
// GetShardState returns the deserialized shard state object.
|
||||||
|
func (h *Header) GetShardState() (shard.State, error) { |
||||||
|
shardState := shard.State{} |
||||||
|
err := rlp.DecodeBytes(h.ShardState(), &shardState) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return shardState, nil |
||||||
|
} |
||||||
|
|
||||||
|
// Copy returns a copy of the given header.
|
||||||
|
func (h *Header) Copy() blockif.Header { |
||||||
|
cpy := *h |
||||||
|
return &cpy |
||||||
|
} |
Loading…
Reference in new issue