mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-05-29 10:16:45 +00:00

* [NOD-1579] Rename AcceptedTxIDs to AcceptedTransactionIDs. * [NOD-1579] Add InsertBlockResult to ValidateAndInsertBlock results. * [NOD-1593] Rename InsertBlockResult to BlockInsertionResult. * [NOD-1593] Add SelectedParentChainChanges to AddBlockToVirtual's result. * [NOD-1593] Implement findSelectedParentChainChanges. * [NOD-1593] Implement TestFindSelectedParentChainChanges. * [NOD-1593] Fix a string. * [NOD-1593] Finish implementing TestFindSelectedParentChainChanges. * [NOD-1593] Fix merge errors. * [NOD-1597] Begin implementing UTXOIndex. * [NOD-1597] Connect UTXOIndex to RPC. * [NOD-1597] Connect Consensus to UTXOIndex. * [NOD-1597] Add AcceptanceData to BlockInfo. * [NOD-1597] Implement UTXOIndex.Update(). * [NOD-1597] Implement add(), remove(), and discard() in utxoIndexStore. * [NOD-1597] Add error cases to add() and remove(). * [NOD-1597] Add special cases to add() and remove(). * [NOD-1597] Implement commit. * [NOD-1597] Add a mutex around UTXOIndex.Update(). * [NOD-1597] Return changes to the UTXO from Update(). * [NOD-1597] Add NotifyUTXOsChangedRequestMessage and related structs. * [NOD-1597] Implement HandleNotifyUTXOsChanged. * [NOD-1597] Begin implementing TestUTXOIndex. * [NOD-1597] Implement RegisterForUTXOsChangedNotifications. * [NOD-1597] Fix bad transaction.ID usage. * [NOD-1597] Implement convertUTXOChangesToUTXOsChangedNotification. * [NOD-1597] Make UTXOsChangedNotificationMessage.Removed UTXOsByAddressesEntry instead of just RPCOutpoint so that the client can discern which address was the UTXO removed for. * [NOD-1597] Collect outpoints in TestUTXOIndex. * [NOD-1597] Rename RPC stuff. * [NOD-1597] Add messages for GetUTXOsByAddresses. * [NOD-1597] Implement HandleGetUTXOsByAddresses. * [NOD-1597] Implement GetUTXOsByAddresses. * [NOD-1597] Implement UTXOs(). * [NOD-1597] Implement getUTXOOutpointEntryPairs(). * [NOD-1597] Expand TestUTXOIndex. * [NOD-1597] Convert SubmitTransaction to use RPCTransaction instead of MsgTx. * [NOD-1597] Finish implementing TestUTXOIndex. * [NOD-1597] Add messages for GetVirtualSelectedParentBlueScore. * [NOD-1597] Implement HandleGetVirtualSelectedParentBlueScore and GetVirtualSelectedParentBlueScore. * [NOD-1597] Implement TestVirtualSelectedParentBlueScore. * [NOD-1597] Implement NotifyVirtualSelectedParentBlueScoreChanged. * [NOD-1597] Expand TestVirtualSelectedParentBlueScore. * [NOD-1597] Implement notifyVirtualSelectedParentBlueScoreChanged. * [NOD-1597] Make go lint happy. * [NOD-1593] Fix merge errors. * [NOD-1593] Rename findSelectedParentChainChanges to calculateSelectedParentChainChanges. * [NOD-1593] Expand TestCalculateSelectedParentChainChanges. * [NOD-1597] Add logs to utxoindex.go. * [NOD-1597] Add logs to utxoindex/store.go. * [NOD-1597] Add logs to RPCManager.NotifyXXX functions. * [NOD-1597] Ignore transactions that aren't accepted. * [NOD-1597] Use GetBlockAcceptanceData instead of GetBlockInfo. * [NOD-1597] Convert scriptPublicKey to string directly, instead of using hex. * [NOD-1597] Add a comment. * [NOD-1597] Guard against calling utxoindex methods when utxoindex is turned off. * [NOD-1597] Add lock to UTXOs. * [NOD-1597] Guard against calls to getUTXOOutpointEntryPairs when staging isn't empty.
270 lines
9.3 KiB
Go
270 lines
9.3 KiB
Go
package appmessage
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionid"
|
|
"github.com/kaspanet/kaspad/util/mstime"
|
|
)
|
|
|
|
// DomainBlockToMsgBlock converts an externalapi.DomainBlock to MsgBlock
|
|
func DomainBlockToMsgBlock(domainBlock *externalapi.DomainBlock) *MsgBlock {
|
|
msgTxs := make([]*MsgTx, 0, len(domainBlock.Transactions))
|
|
for _, domainTransaction := range domainBlock.Transactions {
|
|
msgTxs = append(msgTxs, DomainTransactionToMsgTx(domainTransaction))
|
|
}
|
|
return &MsgBlock{
|
|
Header: *DomainBlockHeaderToBlockHeader(domainBlock.Header),
|
|
Transactions: msgTxs,
|
|
}
|
|
}
|
|
|
|
// DomainBlockHeaderToBlockHeader converts an externalapi.DomainBlockHeader to MsgBlockHeader
|
|
func DomainBlockHeaderToBlockHeader(domainBlockHeader *externalapi.DomainBlockHeader) *MsgBlockHeader {
|
|
return &MsgBlockHeader{
|
|
Version: domainBlockHeader.Version,
|
|
ParentHashes: domainBlockHeader.ParentHashes,
|
|
HashMerkleRoot: &domainBlockHeader.HashMerkleRoot,
|
|
AcceptedIDMerkleRoot: &domainBlockHeader.AcceptedIDMerkleRoot,
|
|
UTXOCommitment: &domainBlockHeader.UTXOCommitment,
|
|
Timestamp: mstime.UnixMilliseconds(domainBlockHeader.TimeInMilliseconds),
|
|
Bits: domainBlockHeader.Bits,
|
|
Nonce: domainBlockHeader.Nonce,
|
|
}
|
|
}
|
|
|
|
// MsgBlockToDomainBlock converts a MsgBlock to externalapi.DomainBlock
|
|
func MsgBlockToDomainBlock(msgBlock *MsgBlock) *externalapi.DomainBlock {
|
|
transactions := make([]*externalapi.DomainTransaction, 0, len(msgBlock.Transactions))
|
|
for _, msgTx := range msgBlock.Transactions {
|
|
transactions = append(transactions, MsgTxToDomainTransaction(msgTx))
|
|
}
|
|
|
|
return &externalapi.DomainBlock{
|
|
Header: BlockHeaderToDomainBlockHeader(&msgBlock.Header),
|
|
Transactions: transactions,
|
|
}
|
|
}
|
|
|
|
// BlockHeaderToDomainBlockHeader converts a MsgBlockHeader to externalapi.DomainBlockHeader
|
|
func BlockHeaderToDomainBlockHeader(blockHeader *MsgBlockHeader) *externalapi.DomainBlockHeader {
|
|
return &externalapi.DomainBlockHeader{
|
|
Version: blockHeader.Version,
|
|
ParentHashes: blockHeader.ParentHashes,
|
|
HashMerkleRoot: *blockHeader.HashMerkleRoot,
|
|
AcceptedIDMerkleRoot: *blockHeader.AcceptedIDMerkleRoot,
|
|
UTXOCommitment: *blockHeader.UTXOCommitment,
|
|
TimeInMilliseconds: blockHeader.Timestamp.UnixMilliseconds(),
|
|
Bits: blockHeader.Bits,
|
|
Nonce: blockHeader.Nonce,
|
|
}
|
|
}
|
|
|
|
// DomainTransactionToMsgTx converts an externalapi.DomainTransaction into an MsgTx
|
|
func DomainTransactionToMsgTx(domainTransaction *externalapi.DomainTransaction) *MsgTx {
|
|
txIns := make([]*TxIn, 0, len(domainTransaction.Inputs))
|
|
for _, input := range domainTransaction.Inputs {
|
|
txIns = append(txIns, domainTransactionInputToTxIn(input))
|
|
}
|
|
|
|
txOuts := make([]*TxOut, 0, len(domainTransaction.Outputs))
|
|
for _, output := range domainTransaction.Outputs {
|
|
txOuts = append(txOuts, domainTransactionOutputToTxOut(output))
|
|
}
|
|
|
|
return &MsgTx{
|
|
Version: domainTransaction.Version,
|
|
TxIn: txIns,
|
|
TxOut: txOuts,
|
|
LockTime: domainTransaction.LockTime,
|
|
SubnetworkID: domainTransaction.SubnetworkID,
|
|
Gas: domainTransaction.Gas,
|
|
PayloadHash: domainTransaction.PayloadHash,
|
|
Payload: domainTransaction.Payload,
|
|
}
|
|
}
|
|
|
|
func domainTransactionOutputToTxOut(domainTransactionOutput *externalapi.DomainTransactionOutput) *TxOut {
|
|
return &TxOut{
|
|
Value: domainTransactionOutput.Value,
|
|
ScriptPubKey: domainTransactionOutput.ScriptPublicKey,
|
|
}
|
|
}
|
|
|
|
func domainTransactionInputToTxIn(domainTransactionInput *externalapi.DomainTransactionInput) *TxIn {
|
|
return &TxIn{
|
|
PreviousOutpoint: *domainOutpointToOutpoint(domainTransactionInput.PreviousOutpoint),
|
|
SignatureScript: domainTransactionInput.SignatureScript,
|
|
Sequence: domainTransactionInput.Sequence,
|
|
}
|
|
}
|
|
|
|
func domainOutpointToOutpoint(domainOutpoint externalapi.DomainOutpoint) *Outpoint {
|
|
return NewOutpoint(
|
|
&domainOutpoint.TransactionID,
|
|
domainOutpoint.Index)
|
|
}
|
|
|
|
// MsgTxToDomainTransaction converts an MsgTx into externalapi.DomainTransaction
|
|
func MsgTxToDomainTransaction(msgTx *MsgTx) *externalapi.DomainTransaction {
|
|
transactionInputs := make([]*externalapi.DomainTransactionInput, 0, len(msgTx.TxIn))
|
|
for _, txIn := range msgTx.TxIn {
|
|
transactionInputs = append(transactionInputs, txInToDomainTransactionInput(txIn))
|
|
}
|
|
|
|
transactionOutputs := make([]*externalapi.DomainTransactionOutput, 0, len(msgTx.TxOut))
|
|
for _, txOut := range msgTx.TxOut {
|
|
transactionOutputs = append(transactionOutputs, txOutToDomainTransactionOutput(txOut))
|
|
}
|
|
|
|
payload := make([]byte, 0)
|
|
if msgTx.Payload != nil {
|
|
payload = msgTx.Payload
|
|
}
|
|
|
|
return &externalapi.DomainTransaction{
|
|
Version: msgTx.Version,
|
|
Inputs: transactionInputs,
|
|
Outputs: transactionOutputs,
|
|
LockTime: msgTx.LockTime,
|
|
SubnetworkID: msgTx.SubnetworkID,
|
|
Gas: msgTx.Gas,
|
|
PayloadHash: msgTx.PayloadHash,
|
|
Payload: payload,
|
|
}
|
|
}
|
|
|
|
func txOutToDomainTransactionOutput(txOut *TxOut) *externalapi.DomainTransactionOutput {
|
|
return &externalapi.DomainTransactionOutput{
|
|
Value: txOut.Value,
|
|
ScriptPublicKey: txOut.ScriptPubKey,
|
|
}
|
|
}
|
|
|
|
func txInToDomainTransactionInput(txIn *TxIn) *externalapi.DomainTransactionInput {
|
|
return &externalapi.DomainTransactionInput{
|
|
PreviousOutpoint: *outpointToDomainOutpoint(&txIn.PreviousOutpoint), //TODO
|
|
SignatureScript: txIn.SignatureScript,
|
|
Sequence: txIn.Sequence,
|
|
}
|
|
}
|
|
|
|
func outpointToDomainOutpoint(outpoint *Outpoint) *externalapi.DomainOutpoint {
|
|
return &externalapi.DomainOutpoint{
|
|
TransactionID: outpoint.TxID,
|
|
Index: outpoint.Index,
|
|
}
|
|
}
|
|
|
|
// RPCTransactionToDomainTransaction converts RPCTransactions to DomainTransactions
|
|
func RPCTransactionToDomainTransaction(rpcTransaction *RPCTransaction) (*externalapi.DomainTransaction, error) {
|
|
inputs := make([]*externalapi.DomainTransactionInput, len(rpcTransaction.Inputs))
|
|
for i, input := range rpcTransaction.Inputs {
|
|
transactionIDBytes, err := hex.DecodeString(input.PreviousOutpoint.TransactionID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
transactionID, err := transactionid.FromBytes(transactionIDBytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
previousOutpoint := &externalapi.DomainOutpoint{
|
|
TransactionID: *transactionID,
|
|
Index: input.PreviousOutpoint.Index,
|
|
}
|
|
signatureScript, err := hex.DecodeString(input.SignatureScript)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
inputs[i] = &externalapi.DomainTransactionInput{
|
|
PreviousOutpoint: *previousOutpoint,
|
|
SignatureScript: signatureScript,
|
|
Sequence: input.Sequence,
|
|
}
|
|
}
|
|
outputs := make([]*externalapi.DomainTransactionOutput, len(rpcTransaction.Outputs))
|
|
for i, output := range rpcTransaction.Outputs {
|
|
scriptPublicKey, err := hex.DecodeString(output.ScriptPubKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
outputs[i] = &externalapi.DomainTransactionOutput{
|
|
Value: output.Amount,
|
|
ScriptPublicKey: scriptPublicKey,
|
|
}
|
|
}
|
|
|
|
subnetworkIDBytes, err := hex.DecodeString(rpcTransaction.SubnetworkID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
subnetworkID, err := subnetworks.FromBytes(subnetworkIDBytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
payloadHashBytes, err := hex.DecodeString(rpcTransaction.PayloadHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
payloadHash, err := hashes.FromBytes(payloadHashBytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
payload, err := hex.DecodeString(rpcTransaction.Payload)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &externalapi.DomainTransaction{
|
|
Version: rpcTransaction.Version,
|
|
Inputs: inputs,
|
|
Outputs: outputs,
|
|
LockTime: rpcTransaction.LockTime,
|
|
SubnetworkID: *subnetworkID,
|
|
Gas: rpcTransaction.LockTime,
|
|
PayloadHash: *payloadHash,
|
|
Payload: payload,
|
|
}, nil
|
|
}
|
|
|
|
// DomainTransactionToRPCTransaction converts DomainTransactions to RPCTransactions
|
|
func DomainTransactionToRPCTransaction(transaction *externalapi.DomainTransaction) *RPCTransaction {
|
|
inputs := make([]*RPCTransactionInput, len(transaction.Inputs))
|
|
for i, input := range transaction.Inputs {
|
|
transactionID := hex.EncodeToString(input.PreviousOutpoint.TransactionID[:])
|
|
previousOutpoint := &RPCOutpoint{
|
|
TransactionID: transactionID,
|
|
Index: input.PreviousOutpoint.Index,
|
|
}
|
|
signatureScript := hex.EncodeToString(input.SignatureScript)
|
|
inputs[i] = &RPCTransactionInput{
|
|
PreviousOutpoint: previousOutpoint,
|
|
SignatureScript: signatureScript,
|
|
Sequence: input.Sequence,
|
|
}
|
|
}
|
|
outputs := make([]*RPCTransactionOutput, len(transaction.Outputs))
|
|
for i, output := range transaction.Outputs {
|
|
scriptPublicKey := hex.EncodeToString(output.ScriptPublicKey)
|
|
outputs[i] = &RPCTransactionOutput{
|
|
Amount: output.Value,
|
|
ScriptPubKey: scriptPublicKey,
|
|
}
|
|
}
|
|
subnetworkID := hex.EncodeToString(transaction.SubnetworkID[:])
|
|
payloadHash := hex.EncodeToString(transaction.PayloadHash[:])
|
|
payload := hex.EncodeToString(transaction.Payload)
|
|
return &RPCTransaction{
|
|
Version: transaction.Version,
|
|
Inputs: inputs,
|
|
Outputs: outputs,
|
|
LockTime: transaction.LockTime,
|
|
SubnetworkID: subnetworkID,
|
|
Gas: transaction.LockTime,
|
|
PayloadHash: payloadHash,
|
|
Payload: payload,
|
|
}
|
|
}
|