Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add helper to convert kupo matches into apollo UTxO #16

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions serialization/Address/Address.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type Address struct {
Hrp string
}

func WalletAddressFromBytes(payment []byte, staking []byte, network constants.Network) *Address {
func AddressFromBytes(payment []byte, paymentIsScript bool, staking []byte, stakingIsScript bool, network constants.Network) *Address {
var addr Address
addr.PaymentPart = payment
addr.StakingPart = staking
Expand All @@ -49,12 +49,30 @@ func WalletAddressFromBytes(payment []byte, staking []byte, network constants.Ne
} else {
addr.Network = TESTNET
}
if len(payment) == 0 {
if len(payment) == 0 && len(staking) == 0 {
return nil
} else if len(payment) == 0 {
if stakingIsScript {
addr.AddressType = NONE_SCRIPT
} else {
addr.AddressType = NONE_KEY
}
} else if len(staking) == 0 {
addr.AddressType = KEY_NONE
if paymentIsScript {
addr.AddressType = SCRIPT_NONE
} else {
addr.AddressType = KEY_NONE
}
} else {
addr.AddressType = KEY_KEY
if paymentIsScript && stakingIsScript {
addr.AddressType = SCRIPT_SCRIPT
} else if paymentIsScript && !stakingIsScript {
addr.AddressType = SCRIPT_KEY
} else if !paymentIsScript && stakingIsScript {
addr.AddressType = KEY_SCRIPT
} else {
addr.AddressType = KEY_KEY
}
}
addr.HeaderByte = (addr.AddressType << 4) | addr.Network
addr.Hrp = ComputeHrp(addr.AddressType, addr.Network)
Expand Down
178 changes: 99 additions & 79 deletions txBuilding/Backend/OgmiosChainContext/OgmiosChainContext.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,34 @@ func (occ *OgmiosChainContext) LatestEpoch() Base.Epoch {
}
}

func (occ *OgmiosChainContext) KupoToUtxo(m kugo.Match) UTxO.UTxO {
ctx := context.Background()
addr, au := occ.kupoToAddressUtxo(ctx, m)
return occ.addressUtxoToUtxo(addr, au)
}

func (occ *OgmiosChainContext) kupoToAddressUtxo(ctx context.Context, match kugo.Match) (Address.Address, Base.AddressUTXO) {
datum := ""
var err error
if match.DatumType == "inline" {
datum, err = occ.kugo.Datum(ctx, match.DatumHash)
if err != nil {
log.Fatal(err, "OgmiosChainContext: AddressUtxos: kupo datum request failed")
}
}
am := statequeryValue_toAddressAmount(shared.Value(match.Value))
addr, _ := Address.DecodeAddress(match.Address)
return addr, Base.AddressUTXO{
TxHash: match.TransactionID,
OutputIndex: match.OutputIndex,
Amount: am,
// We probably don't need this info and kupo doesn't provide it in this query
Block: "",
DataHash: match.DatumHash,
InlineDatum: datum,
}
}

func (occ *OgmiosChainContext) AddressUtxos(address string, gather bool) []Base.AddressUTXO {
ctx := context.Background()
addressUtxos := make([]Base.AddressUTXO, 0)
Expand All @@ -328,23 +356,8 @@ func (occ *OgmiosChainContext) AddressUtxos(address string, gather bool) []Base.
log.Fatal(err, "OgmiosChainContext: AddressUtxos: kupo request failed")
}
for _, match := range matches {
datum := ""
if match.DatumType == "inline" {
datum, err = occ.kugo.Datum(ctx, match.DatumHash)
if err != nil {
log.Fatal(err, "OgmiosChainContext: AddressUtxos: kupo datum request failed")
}
}
am := statequeryValue_toAddressAmount(shared.Value(match.Value))
addressUtxos = append(addressUtxos, Base.AddressUTXO{
TxHash: match.TransactionID,
OutputIndex: match.OutputIndex,
Amount: am,
// We probably don't need this info and kupo doesn't provide it in this query
Block: "",
DataHash: match.DatumHash,
InlineDatum: datum,
})
_, addrUtxo := occ.kupoToAddressUtxo(ctx, match)
addressUtxos = append(addressUtxos, addrUtxo)
}
return addressUtxos

Expand Down Expand Up @@ -557,76 +570,83 @@ func (occ *OgmiosChainContext) MaxTxFee() int {
return Base.Fee(occ, protocol_param.MaxTxSize, maxTxExSteps, maxTxExMem)
}

// Copied from blockfrost context def since it just calls AddressUtxos and then
// converts
func (occ *OgmiosChainContext) Utxos(address Address.Address) []UTxO.UTxO {
results := occ.AddressUtxos(address.String(), true)
utxos := make([]UTxO.UTxO, 0)
for _, result := range results {
decodedTxId, _ := hex.DecodeString(result.TxHash)
tx_in := TransactionInput.TransactionInput{TransactionId: decodedTxId, Index: result.OutputIndex}
amount := result.Amount
lovelace_amount := 0
multi_assets := MultiAsset.MultiAsset[int64]{}
for _, item := range amount {
if item.Unit == "lovelace" {
amount, err := strconv.Atoi(item.Quantity)
if err != nil {
log.Fatal(err)
}
lovelace_amount += amount
} else {
asset_quantity, err := strconv.ParseInt(item.Quantity, 10, 64)
if err != nil {
log.Fatal(err)
}
policy_id := Policy.PolicyId{Value: item.Unit[:56]}
asset_name := *AssetName.NewAssetNameFromHexString(item.Unit[56:])
_, ok := multi_assets[policy_id]
if !ok {
multi_assets[policy_id] = Asset.Asset[int64]{}
}
multi_assets[policy_id][asset_name] = int64(asset_quantity)
}
}
final_amount := Value.Value{}
if len(multi_assets) > 0 {
final_amount = Value.Value{Am: Amount.Amount{Coin: int64(lovelace_amount), Value: multi_assets}, HasAssets: true}
} else {
final_amount = Value.Value{Coin: int64(lovelace_amount), HasAssets: false}
}
datum_hash := serialization.DatumHash{}
if result.DataHash != "" && result.InlineDatum == "" {

datum_hash = serialization.DatumHash{}
copy(datum_hash.Payload[:], result.DataHash[:])
}
var tx_out TransactionOutput.TransactionOutput
if result.InlineDatum != "" {
decoded, err := hex.DecodeString(result.InlineDatum)
func (occ *OgmiosChainContext) addressUtxoToUtxo(address Address.Address, result Base.AddressUTXO) UTxO.UTxO {
decodedTxId, _ := hex.DecodeString(result.TxHash)
tx_in := TransactionInput.TransactionInput{TransactionId: decodedTxId, Index: result.OutputIndex}
amount := result.Amount
lovelace_amount := 0
multi_assets := MultiAsset.MultiAsset[int64]{}
for _, item := range amount {
if item.Unit == "lovelace" {
amount, err := strconv.Atoi(item.Quantity)
if err != nil {
log.Fatal(err)
}
var x PlutusData.PlutusData
err = cbor.Unmarshal(decoded, &x)
lovelace_amount += amount
} else {
asset_quantity, err := strconv.ParseInt(item.Quantity, 10, 64)
if err != nil {
log.Fatal(err)
}
l := PlutusData.DatumOptionInline(&x)
tx_out = TransactionOutput.TransactionOutput{IsPostAlonzo: true,
PostAlonzo: TransactionOutput.TransactionOutputAlonzo{
Address: address,
Amount: final_amount.ToAlonzoValue(),
Datum: &l},
policy_id := Policy.PolicyId{Value: item.Unit[:56]}
asset_name := *AssetName.NewAssetNameFromHexString(item.Unit[56:])
_, ok := multi_assets[policy_id]
if !ok {
multi_assets[policy_id] = Asset.Asset[int64]{}
}
} else {
tx_out = TransactionOutput.TransactionOutput{PreAlonzo: TransactionOutput.TransactionOutputShelley{
Address: address,
Amount: final_amount,
DatumHash: datum_hash,
HasDatum: len(datum_hash.Payload) > 0}, IsPostAlonzo: false}
multi_assets[policy_id][asset_name] = int64(asset_quantity)
}
}
final_amount := Value.Value{}
if len(multi_assets) > 0 {
final_amount = Value.Value{Am: Amount.Amount{Coin: int64(lovelace_amount), Value: multi_assets}, HasAssets: true}
} else {
final_amount = Value.Value{Coin: int64(lovelace_amount), HasAssets: false}
}
datum_hash := serialization.DatumHash{}
if result.DataHash != "" && result.InlineDatum == "" {

datum_hash = serialization.DatumHash{}
copy(datum_hash.Payload[:], result.DataHash[:])
}
var tx_out TransactionOutput.TransactionOutput
if result.InlineDatum != "" {
decoded, err := hex.DecodeString(result.InlineDatum)
if err != nil {
log.Fatal(err)
}
var x PlutusData.PlutusData
err = cbor.Unmarshal(decoded, &x)
if err != nil {
log.Fatal(err)
}
l := PlutusData.DatumOptionInline(&x)
tx_out = TransactionOutput.TransactionOutput{IsPostAlonzo: true,
PostAlonzo: TransactionOutput.TransactionOutputAlonzo{
Address: address,
Amount: final_amount.ToAlonzoValue(),
Datum: &l},
}
utxos = append(utxos, UTxO.UTxO{Input: tx_in, Output: tx_out})
} else {
tx_out = TransactionOutput.TransactionOutput{PreAlonzo: TransactionOutput.TransactionOutputShelley{
Address: address,
Amount: final_amount,
DatumHash: datum_hash,
HasDatum: len(datum_hash.Payload) > 0}, IsPostAlonzo: false}
}
return UTxO.UTxO{
Input: tx_in,
Output: tx_out,
}
}

// Copied from blockfrost context def since it just calls AddressUtxos and then
// converts
func (occ *OgmiosChainContext) Utxos(address Address.Address) []UTxO.UTxO {
results := occ.AddressUtxos(address.String(), true)
utxos := make([]UTxO.UTxO, 0)
for _, result := range results {
utxos = append(utxos, occ.addressUtxoToUtxo(address, result))
}
return utxos
}
Expand Down