| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- package vm
- import (
- "bytes"
- "encoding/binary"
- "fmt"
- "github.com/coredao-org/btcpowermirror/lightmirror"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/params"
- )
- const (
- uint64TypeLength uint64 = 8
- precompileContractInputMetaDataLength uint64 = 32
- )
- // btcValidate implemented as a precompiled contract.
- type btcValidate struct{}
- func (c *btcValidate) RequiredGas(input []byte) uint64 {
- return params.BitcoinHeaderValidateGas + uint64(len(input)/32)*params.IAVLMerkleProofValidateGas
- }
- func (c *btcValidate) Run(input []byte) (result []byte, err error) {
- defer func() {
- if r := recover(); r != nil {
- err = fmt.Errorf("internal error: %v\n", r)
- }
- }()
- if uint64(len(input)) <= precompileContractInputMetaDataLength {
- return nil, fmt.Errorf("invalid input")
- }
- payloadLength := binary.BigEndian.Uint64(input[precompileContractInputMetaDataLength-uint64TypeLength : precompileContractInputMetaDataLength])
- if uint64(len(input)) != payloadLength+precompileContractInputMetaDataLength {
- return nil, fmt.Errorf("invalid input: input size should be %d, actual size is %d", payloadLength+precompileContractInputMetaDataLength, len(input))
- }
- rbuf := bytes.NewReader(input[precompileContractInputMetaDataLength:])
- var mirror lightmirror.BtcLightMirror
- err = mirror.Deserialize(rbuf)
- if err != nil {
- err = fmt.Errorf("deserialize btcLightMirror failed %s", err.Error())
- return nil, err
- }
- // Verify MerkleRoot & coinbaseTx
- err = mirror.CheckMerkle()
- if err != nil {
- err = fmt.Errorf("verify btcLightMirror failed %s", err.Error())
- return nil, err
- }
- coinbaseAddr, addrType := mirror.GetCoinbaseAddress()
- // result
- // | coinbaseAddr |
- // | 20 bytes + 12 bytes |
- addrTypeBytes := make([]byte, 4)
- binary.BigEndian.PutUint32(addrTypeBytes, (uint32)(addrType))
- addrTypeBytes = common.LeftPadBytes(addrTypeBytes[:], 32)
- return append(common.RightPadBytes(coinbaseAddr[:], 32), addrTypeBytes...), nil
- }
|