diff --git a/sharding/collation.go b/sharding/collation.go index 10fea6e40..cf3cfe711 100644 --- a/sharding/collation.go +++ b/sharding/collation.go @@ -4,6 +4,8 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto/sha3" + "github.com/ethereum/go-ethereum/rlp" ) type Collation struct { @@ -19,6 +21,14 @@ type CollationHeader struct { proposerSignature []byte //the proposer's signature for calculating collation hash } +// Hash takes the keccak256 of the collation header's contents. +func (h *CollationHeader) Hash() (hash common.Hash) { + hw := sha3.NewKeccak256() + rlp.Encode(hw, h) + hw.Sum(hash[:0]) + return hash +} + 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 } diff --git a/sharding/db.go b/sharding/db.go index 22519b44c..9e3889eeb 100644 --- a/sharding/db.go +++ b/sharding/db.go @@ -1,21 +1,29 @@ package sharding -import "github.com/ethereum/go-ethereum/common" +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" +) type shardBackend struct { - kv map[*common.Hash][]byte + kv map[common.Hash][]byte } -func (sb *shardBackend) Get(k *common.Hash) []byte { - return sb.kv[k] +func (sb *shardBackend) Get(k common.Hash) ([]byte, error) { + v := sb.kv[k] + if v == nil { + return nil, fmt.Errorf("Key Not Found") + } + return v, nil } -func (sb *shardBackend) Put(k *common.Hash, v []byte) { +func (sb *shardBackend) Put(k common.Hash, v []byte) { sb.kv[k] = v return } -func (sb *shardBackend) Delete(k *common.Hash) { +func (sb *shardBackend) Delete(k common.Hash) { delete(sb.kv, k) return } diff --git a/sharding/shard.go b/sharding/shard.go index 886315baf..38de4f9b7 100644 --- a/sharding/shard.go +++ b/sharding/shard.go @@ -22,28 +22,39 @@ func (s *Shard) ValidateShardID(h *CollationHeader) error { return nil } +// SetHeader adds the collation header to shardDB +func (s *Shard) SetHeader(h *CollationHeader) error { + if err := s.ValidateShardID(h); err != nil { + return err + } + encoded, err := rlp.EncodeToBytes(h) + if err != nil { + return fmt.Errorf("Error: Cannot Encode Header") + } + s.shardDB.Put(h.Hash(), encoded) + return nil +} + // GetHeaderByHash of collation. -func (s *Shard) GetHeaderByHash(hash *common.Hash) (*CollationHeader, error) { - encoded := s.shardDB.Get(hash) +func (s *Shard) GetHeaderByHash(hash common.Hash) (*CollationHeader, error) { + encoded, err := s.shardDB.Get(hash) + if err != nil { + return nil, fmt.Errorf("Error: Header Not Found") + } var header CollationHeader if err := rlp.DecodeBytes(encoded, &header); err != nil { - return nil, fmt.Errorf("Error Decoding Header: %v", err) + return nil, fmt.Errorf("Error: Problem 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) { +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) + body, err := s.GetBodyByChunkRoot(*header.chunkRoot) if err != nil { return nil, err } @@ -51,9 +62,9 @@ func (s *Shard) GetCollationByHash(hash *common.Hash) (*Collation, error) { } // GetBodyByChunkRoot fetches a collation body -func (s *Shard) GetBodyByChunkRoot(chunkRoot *common.Hash) ([]byte, error) { - body := s.shardDB.Get(chunkRoot) - if body == nil { +func (s *Shard) GetBodyByChunkRoot(chunkRoot common.Hash) ([]byte, error) { + body, err := s.shardDB.Get(chunkRoot) + if err != nil { return nil, fmt.Errorf("Error: No Corresponding Body With Chunk Root Found") } return body, nil @@ -68,11 +79,3 @@ func (s *Shard) CheckAvailability(header *CollationHeader) bool { 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