Skip to content
Snippets Groups Projects
Commit be5848e6 authored by lunfardo314's avatar lunfardo314
Browse files

- fixed bug of non-deterministic NewOutputs function

- added function to sort slice of addresses
- minor edits
parent 2173a9dd
No related branches found
No related tags found
No related merge requests found
package address
import (
"bytes"
"sort"
)
type sortedAddresses []Address
func (s sortedAddresses) Len() int {
return len(s)
}
func (s sortedAddresses) Less(i, j int) bool {
return bytes.Compare(s[i][:], s[j][:]) < 0
}
func (s sortedAddresses) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
// Sort function sorts the slice of addresses
func Sort(addresses []Address) {
sort.Sort(sortedAddresses(addresses))
}
...@@ -16,11 +16,17 @@ type Outputs struct { ...@@ -16,11 +16,17 @@ type Outputs struct {
// NewOutputs is the constructor of the Outputs struct and creates the list of Outputs from the given details. // NewOutputs is the constructor of the Outputs struct and creates the list of Outputs from the given details.
func NewOutputs(outputs map[address.Address][]*balance.Balance) (result *Outputs) { func NewOutputs(outputs map[address.Address][]*balance.Balance) (result *Outputs) {
result = &Outputs{orderedmap.New()} // sorting outputs first before adding to the ordered map to have a deterministic order
for address, balances := range outputs { toSort := make([]address.Address, 0, len(outputs))
result.Add(address, balances) for a := range outputs {
toSort = append(toSort, a)
} }
address.Sort(toSort)
result = &Outputs{orderedmap.New()}
for _, addr := range toSort {
result.Add(addr, outputs[addr])
}
return return
} }
...@@ -49,7 +55,7 @@ func OutputsFromBytes(bytes []byte, optionalTargetObject ...*Outputs) (result *O ...@@ -49,7 +55,7 @@ func OutputsFromBytes(bytes []byte, optionalTargetObject ...*Outputs) (result *O
// iterate the corresponding times and collect addresses + their details // iterate the corresponding times and collect addresses + their details
for i := uint32(0); i < addressCount; i++ { for i := uint32(0); i < addressCount; i++ {
// read address // read address
address, addressErr := address.Parse(marshalUtil) addr, addressErr := address.Parse(marshalUtil)
if addressErr != nil { if addressErr != nil {
err = addressErr err = addressErr
...@@ -78,7 +84,7 @@ func OutputsFromBytes(bytes []byte, optionalTargetObject ...*Outputs) (result *O ...@@ -78,7 +84,7 @@ func OutputsFromBytes(bytes []byte, optionalTargetObject ...*Outputs) (result *O
} }
// add the gathered information as an output // add the gathered information as an output
result.Add(address, coloredBalances) result.Add(addr, coloredBalances)
} }
// return the number of bytes we processed // return the number of bytes we processed
...@@ -117,8 +123,8 @@ func (outputs *Outputs) Bytes() []byte { ...@@ -117,8 +123,8 @@ func (outputs *Outputs) Bytes() []byte {
marshalUtil.WriteBytes(address.Bytes()) marshalUtil.WriteBytes(address.Bytes())
marshalUtil.WriteUint32(uint32(len(balances))) marshalUtil.WriteUint32(uint32(len(balances)))
for _, balance := range balances { for _, bal := range balances {
marshalUtil.WriteBytes(balance.Bytes()) marshalUtil.WriteBytes(bal.Bytes())
} }
return true return true
...@@ -141,10 +147,10 @@ func (outputs *Outputs) String() string { ...@@ -141,10 +147,10 @@ func (outputs *Outputs) String() string {
result += " " + address.String() + ": [\n" result += " " + address.String() + ": [\n"
balancesEmpty := true balancesEmpty := true
for _, balance := range balances { for _, bal := range balances {
balancesEmpty = false balancesEmpty = false
result += " " + balance.String() + ",\n" result += " " + bal.String() + ",\n"
} }
if balancesEmpty { if balancesEmpty {
......
package transaction
import (
"bytes"
"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address"
"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance"
"github.com/magiconair/properties/assert"
"golang.org/x/crypto/blake2b"
"testing"
)
func TestOutputs(t *testing.T) {
rndAddrs := make([]address.Address, 15)
for i := range rndAddrs {
rndAddrs[i] = address.RandomOfType(address.VersionED25519)
}
theMap1 := make(map[address.Address][]*balance.Balance)
for i := 0; i < len(rndAddrs); i++ {
theMap1[rndAddrs[i]] = []*balance.Balance{balance.New(balance.ColorIOTA, int64(i))}
}
out1 := NewOutputs(theMap1)
theMap2 := make(map[address.Address][]*balance.Balance)
for i := len(rndAddrs) - 1; i >= 0; i-- {
theMap2[rndAddrs[i]] = []*balance.Balance{balance.New(balance.ColorIOTA, int64(i))}
}
out2 := NewOutputs(theMap2)
//t.Logf("%s", out1.String())
//t.Logf("%s", out2.String())
h1 := hashOutputs(t, out1)
h2 := hashOutputs(t, out2)
assert.Equal(t, bytes.Equal(h1, h2), true)
}
func hashOutputs(t *testing.T, out *Outputs) []byte {
h, err := blake2b.New256(nil)
assert.Equal(t, err, nil)
h.Write(out.Bytes())
return h.Sum(nil)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment