mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-09 19:21:19 +00:00
84 lines
2.9 KiB
Go
84 lines
2.9 KiB
Go
package syncer
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/prysmaticlabs/prysm/client/mainchain"
|
|
"github.com/prysmaticlabs/prysm/client/types"
|
|
pb "github.com/prysmaticlabs/prysm/proto/sharding/v1"
|
|
"github.com/prysmaticlabs/prysm/shared/p2p"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var log = logrus.WithField("prefix", "syncer")
|
|
|
|
// RespondCollationBody is called by a node responding to another node's request
|
|
// for a collation body given a (shardID, chunkRoot, period, proposerAddress) tuple.
|
|
// The proposer will fetch the corresponding data from persistent storage (shardDB) by
|
|
// constructing a collation header from the input and calculating its hash.
|
|
func RespondCollationBody(req p2p.Message, collationFetcher types.CollationFetcher) (*pb.CollationBodyResponse, error) {
|
|
// Type assertion helps us catch incorrect data requests.
|
|
msg, ok := req.Data.(*pb.CollationBodyRequest)
|
|
if !ok {
|
|
log.Debugf("Request data type: %T", req.Data)
|
|
return nil, fmt.Errorf("received incorrect data request type. Data: %+v", msg)
|
|
}
|
|
|
|
shardID := new(big.Int).SetUint64(msg.ShardId)
|
|
chunkRoot := common.BytesToHash(msg.ChunkRoot)
|
|
period := new(big.Int).SetUint64(msg.Period)
|
|
proposer := common.BytesToAddress(msg.ProposerAddress)
|
|
var sig [32]byte
|
|
if len(msg.Signature) >= 32 {
|
|
copy(sig[:], msg.Signature[0:32])
|
|
}
|
|
header := types.NewCollationHeader(shardID, &chunkRoot, period, &proposer, sig)
|
|
|
|
// Fetch the collation by its header hash from the shardChainDB.
|
|
headerHash := header.Hash()
|
|
collation, err := collationFetcher.CollationByHeaderHash(&headerHash)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not fetch collation: %v", err)
|
|
}
|
|
if collation == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
return &pb.CollationBodyResponse{HeaderHash: headerHash.Bytes(), Body: collation.Body()}, nil
|
|
}
|
|
|
|
// RequestCollationBody fetches a collation header record submitted to the SMC for
|
|
// a shardID, period pair and constructs a p2p collationBodyRequest that will
|
|
// then be relayed to the appropriate proposer that submitted the collation header.
|
|
// In production, this will be done within a attester service.
|
|
func RequestCollationBody(fetcher mainchain.RecordFetcher, shardID *big.Int, period *big.Int) (*pb.CollationBodyRequest, error) {
|
|
|
|
record, err := fetcher.CollationRecords(&bind.CallOpts{}, shardID, period)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not fetch collation record from SMC: %v", err)
|
|
}
|
|
|
|
sum := 0
|
|
for _, val := range record.ChunkRoot {
|
|
sum += int(val)
|
|
}
|
|
|
|
if sum == 0 {
|
|
log.Debugf("No collation exists for shard %d and period %d", shardID, period)
|
|
return nil, nil
|
|
}
|
|
|
|
// Converts from fixed size [32]byte to []byte slice.
|
|
chunkRoot := common.BytesToHash(record.ChunkRoot[:])
|
|
|
|
return &pb.CollationBodyRequest{
|
|
ChunkRoot: chunkRoot.Bytes(),
|
|
ShardId: shardID.Uint64(),
|
|
Period: period.Uint64(),
|
|
ProposerAddress: record.Proposer.Bytes(),
|
|
}, nil
|
|
}
|