From 887b72ff111aedcf1acd79d476242a30ff6ce02f Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Thu, 3 May 2018 10:22:28 -0500 Subject: [PATCH] sharding: beginning receiver methods for shard type Former-commit-id: fc39828fa985074ec20fd3ec1a99c612630b8b1f [formerly 89a47cea8d6d4c2ab1aa77d1d713680394dc823e] Former-commit-id: 44edff25e19c39aeefbf08f260373c0976248f74 --- sharding/collation.go | 32 ++++-------------- sharding/db.go | 21 ++++++++++++ sharding/shard.go | 77 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 26 deletions(-) create mode 100644 sharding/db.go diff --git a/sharding/collation.go b/sharding/collation.go index f3e8a81de..10fea6e40 100644 --- a/sharding/collation.go +++ b/sharding/collation.go @@ -1,16 +1,14 @@ package sharding import ( - "math" "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" ) type Collation struct { - header *CollationHeader - transactions []*types.Transaction + header *CollationHeader + body []byte } type CollationHeader struct { @@ -21,27 +19,9 @@ type CollationHeader struct { proposerSignature []byte //the proposer's signature for calculating collation hash } -func (c *Collation) Header() *CollationHeader { return c.header } -func (c *Collation) Transactions() []*types.Transaction { return c.transactions } -func (c *Collation) ShardID() *big.Int { return c.header.shardID } -func (c *Collation) Period() *big.Int { return c.header.period } -func (c *Collation) ProposerAddress() *common.Address { return c.header.proposerAddress } +func (c *Collation) Header() *CollationHeader { return c.header } +func (c *Collation) ShardID() *big.Int { return c.header.shardID } +func (c *Collation) Period() *big.Int { return c.header.period } +func (c *Collation) ProposerAddress() *common.Address { return c.header.proposerAddress } func (c *Collation) SetHeader(h *CollationHeader) { c.header = h } - -func (c *Collation) AddTransaction(tx *types.Transaction) { - // TODO: Check transaction does not exceed gas limit - c.transactions = append(c.transactions, tx) -} - -func (c *Collation) GasUsed() *big.Int { - g := uint64(0) - for _, tx := range c.transactions { - if g > math.MaxUint64-(g+tx.Gas()) { - g = math.MaxUint64 - break - } - g += tx.Gas() - } - return big.NewInt(0).SetUint64(g) -} diff --git a/sharding/db.go b/sharding/db.go new file mode 100644 index 000000000..22519b44c --- /dev/null +++ b/sharding/db.go @@ -0,0 +1,21 @@ +package sharding + +import "github.com/ethereum/go-ethereum/common" + +type shardBackend struct { + kv map[*common.Hash][]byte +} + +func (sb *shardBackend) Get(k *common.Hash) []byte { + return sb.kv[k] +} + +func (sb *shardBackend) Put(k *common.Hash, v []byte) { + sb.kv[k] = v + return +} + +func (sb *shardBackend) Delete(k *common.Hash) { + delete(sb.kv, k) + return +} diff --git a/sharding/shard.go b/sharding/shard.go index ec576df7c..886315baf 100644 --- a/sharding/shard.go +++ b/sharding/shard.go @@ -1 +1,78 @@ package sharding + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" +) + +// Shard base struct. +type Shard struct { + shardDB *shardBackend + shardID *big.Int +} + +// ValidateShardID checks if header belongs to shard. +func (s *Shard) ValidateShardID(h *CollationHeader) error { + if s.shardID.Cmp(h.shardID) != 0 { + return fmt.Errorf("Error: Collation Does Not Belong to Shard %d but Instead Has ShardID %d", h.shardID, s.shardID) + } + return nil +} + +// GetHeaderByHash of collation. +func (s *Shard) GetHeaderByHash(hash *common.Hash) (*CollationHeader, error) { + encoded := s.shardDB.Get(hash) + var header CollationHeader + if err := rlp.DecodeBytes(encoded, &header); err != nil { + return nil, fmt.Errorf("Error Decoding Header: %v", err) + } + return &header, nil +} + +// GetHeaderByPeriod the header was added. +func (s *Shard) GetHeaderByPeriod(period *big.Int) *CollationHeader { + return nil +} + +// GetCollationByHash fetches full collation. +func (s *Shard) GetCollationByHash(hash *common.Hash) (*Collation, error) { + header, err := s.GetHeaderByHash(hash) + if err != nil { + return nil, err + } + body, err := s.GetBodyByChunkRoot(header.chunkRoot) + if err != nil { + return nil, err + } + return &Collation{header: header, body: body}, nil +} + +// GetBodyByChunkRoot fetches a collation body +func (s *Shard) GetBodyByChunkRoot(chunkRoot *common.Hash) ([]byte, error) { + body := s.shardDB.Get(chunkRoot) + if body == nil { + return nil, fmt.Errorf("Error: No Corresponding Body With Chunk Root Found") + } + return body, nil +} + +// CheckAvailability is used by notaries to confirm a header's data availability. +func (s *Shard) CheckAvailability(header *CollationHeader) bool { + return true +} + +// SetUnavailable ensures to set a collation as unavailable in the shardDB. +func (s *Shard) SetUnavailable(header *CollationHeader) error { + return nil +} + +// SetCanonical is called after >= 2/3 notaries vote on header and period ends. +func (s *Shard) SetCanonical(header *CollationHeader) error { + return nil +} + +// Set Header and Set Body Methods +// TODO: error in Get from the kv store