prysm-pulse/beacon-chain/core/helpers/deposits.go
Raul Jordan ab511cb022
Move Deposit Encoding to Helpers Package (#1644)
* move deposits

* finish moving deposit helpers
2019-02-19 12:05:34 -06:00

81 lines
2.7 KiB
Go

package helpers
import (
"bytes"
"encoding/binary"
"fmt"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/ssz"
)
// EncodeDepositData converts a deposit input proto into an a byte slice
// of Simple Serialized deposit input followed by 8 bytes for a deposit value
// and 8 bytes for a unix timestamp, all in LittleEndian format.
func EncodeDepositData(
depositInput *pb.DepositInput,
depositValue uint64,
depositTimestamp int64,
) ([]byte, error) {
wBuf := new(bytes.Buffer)
if err := ssz.Encode(wBuf, depositInput); err != nil {
return nil, fmt.Errorf("failed to encode deposit input: %v", err)
}
encodedInput := wBuf.Bytes()
depositData := make([]byte, 0, 512)
value := make([]byte, 8)
binary.LittleEndian.PutUint64(value, depositValue)
timestamp := make([]byte, 8)
binary.LittleEndian.PutUint64(timestamp, uint64(depositTimestamp))
depositData = append(depositData, value...)
depositData = append(depositData, timestamp...)
depositData = append(depositData, encodedInput...)
return depositData, nil
}
// DecodeDepositInput unmarshals a depositData byte slice into
// a proto *pb.DepositInput by using the Simple Serialize (SSZ)
// algorithm.
// TODO(#1253): Do not assume we will receive serialized proto objects - instead,
// replace completely by a common struct which can be simple serialized.
func DecodeDepositInput(depositData []byte) (*pb.DepositInput, error) {
if len(depositData) < 16 {
return nil, fmt.Errorf(
"deposit data slice too small: len(depositData) = %d",
len(depositData),
)
}
depositInput := new(pb.DepositInput)
// Since the value deposited and the timestamp are both 8 bytes each,
// the deposit data is the chunk after the first 16 bytes.
depositInputBytes := depositData[16:]
rBuf := bytes.NewReader(depositInputBytes)
if err := ssz.Decode(rBuf, depositInput); err != nil {
return nil, fmt.Errorf("ssz decode failed: %v", err)
}
return depositInput, nil
}
// DecodeDepositAmountAndTimeStamp extracts the deposit amount and timestamp
// from the given deposit data.
func DecodeDepositAmountAndTimeStamp(depositData []byte) (uint64, int64, error) {
// Last 16 bytes of deposit data are 8 bytes for value
// and 8 bytes for timestamp. Everything before that is a
// Simple Serialized deposit input value.
if len(depositData) < 16 {
return 0, 0, fmt.Errorf(
"deposit data slice too small: len(depositData) = %d",
len(depositData),
)
}
// the amount occupies the first 8 bytes while the
// timestamp occupies the next 8 bytes.
amount := binary.LittleEndian.Uint64(depositData[:8])
timestamp := binary.LittleEndian.Uint64(depositData[8:16])
return amount, int64(timestamp), nil
}