Skip to content

Commit

Permalink
Merge pull request #37 from libsv/enhancement/feeQuote_marshall
Browse files Browse the repository at this point in the history
Marshal/ Unmarshal feeQuote
  • Loading branch information
mergify[bot] authored Aug 18, 2021
2 parents 0e675cd + 67ae990 commit 26dc44e
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 1 deletion.
51 changes: 50 additions & 1 deletion fees.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package bt

import (
"encoding/json"
"errors"
"fmt"
"sync"
"time"
)
Expand All @@ -13,6 +15,7 @@ var (
ErrFeeTypeNotFound = errors.New("feetype not found")
ErrFeeQuoteNotInit = errors.New("feeQuote has not been initialised, call NewFeeQuote()")
ErrEmptyValues = errors.New("empty value or values passed, all arguments are required and cannot be empty")
ErrUnknownFeeType = "unknown feetype supplied '%s'"
)

// FeeType is used to specify which
Expand Down Expand Up @@ -225,6 +228,52 @@ func (f *FeeQuote) Expired() bool {
return f.expiryTime.Before(time.Now().UTC())
}

// MarshalJSON will convert the FeeQuote to a json object
// with the format as shown:
// {
// "data": {
// "miningFee": {
// "satoshis": 5,
// "bytes": 2
// },
// "relayFee": {
// "satoshis": 8,
// "bytes": 4
// }
// },
// "standard": {
// "miningFee": {
// "satoshis": 100,
// "bytes": 10
// },
// "relayFee": {
// "satoshis": 10,
// "bytes": 5
// }
// }
// }
func (f *FeeQuote) MarshalJSON() ([]byte, error) {
return json.Marshal(f.fees)
}

// UnmarshalJSON will convert a json encoded FeeQuote back into a fee quote type, the expected
// JSON format is shown above in the MarshalJSON function.
// If the fee type supplied is unknown an ErrUnknownFeeType will be returned.
func (f *FeeQuote) UnmarshalJSON(body []byte) error {
fees := map[FeeType]*Fee{}
if err := json.Unmarshal(body, &fees); err != nil {
return err
}
for k, v := range fees {
if k != FeeTypeData && k != FeeTypeStandard {
return fmt.Errorf(ErrUnknownFeeType, k)
}
v.FeeType = k
}
f.fees = fees
return nil
}

// FeeUnit displays the amount of Satoshis needed
// for a specific amount of Bytes in a transaction
// see https://github.com/bitcoin-sv-specs/brfc-misc/tree/master/feespec
Expand All @@ -237,7 +286,7 @@ type FeeUnit struct {
// FeeType, for example 'standard' or 'data'
// see https://github.com/bitcoin-sv-specs/brfc-misc/tree/master/feespec
type Fee struct {
FeeType FeeType `json:"feeType"` // standard || data
FeeType FeeType `json:"-"` // standard || data
MiningFee FeeUnit `json:"miningFee"`
RelayFee FeeUnit `json:"relayFee"` // Fee for retaining Tx in secondary mempool
}
Expand Down
83 changes: 83 additions & 0 deletions fees_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package bt

import (
"encoding/json"
"errors"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -539,3 +541,84 @@ func TestFeeQuotes_Fee(t *testing.T) {
})
}
}

func TestFeeQuote_MarshalUnmarshalJSON(t *testing.T) {
t.Parallel()
tests := map[string]struct {
quote *FeeQuote
err error
}{
"successful run should return no errors": {
quote: &FeeQuote{
fees: map[FeeType]*Fee{
FeeTypeStandard: {
FeeType: FeeTypeStandard,
MiningFee: FeeUnit{
Satoshis: 100,
Bytes: 10,
},
RelayFee: FeeUnit{
Satoshis: 10,
Bytes: 5},
}, FeeTypeData: {
FeeType: FeeTypeData,
MiningFee: FeeUnit{
Satoshis: 5,
Bytes: 2,
},
RelayFee: FeeUnit{
Satoshis: 8,
Bytes: 4},
},
},
},
err: nil,
},
"empty key should error": {
quote: &FeeQuote{
fees: map[FeeType]*Fee{
"": {
FeeType: FeeTypeStandard,
MiningFee: FeeUnit{
Satoshis: 100,
Bytes: 10,
},
RelayFee: FeeUnit{
Satoshis: 10,
Bytes: 5},
},
},
},
err: errors.New("unknown feetype supplied ''"),
}, "random key should error": {
quote: &FeeQuote{
fees: map[FeeType]*Fee{
"idunno": {
FeeType: FeeTypeStandard,
MiningFee: FeeUnit{
Satoshis: 100,
Bytes: 10,
},
RelayFee: FeeUnit{
Satoshis: 10,
Bytes: 5},
},
},
},
err: errors.New("unknown feetype supplied 'idunno'"),
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
bb, _ := json.Marshal(test.quote)
var quote *FeeQuote
err := json.Unmarshal(bb, &quote)
if test.err != nil {
assert.Error(t, err)
assert.EqualError(t, err, test.err.Error())
return
}
assert.Equal(t, test.quote, quote)
})
}
}

0 comments on commit 26dc44e

Please sign in to comment.