Skip to content
Snippets Groups Projects
Commit 48da4d65 authored by Hans Moog's avatar Hans Moog
Browse files

Feat: finished ledgerstate + started implementing multiverse consensus

parent dde7849f
No related branches found
No related tags found
No related merge requests found
package tangle
import (
"github.com/iotaledger/goshimmer/packages/binary/transaction"
"github.com/iotaledger/hive.go/objectstorage"
)
type Tangle struct {
transactionStorage *objectstorage.ObjectStorage
}
func New(storageId string) *Tangle {
return &Tangle{
transactionStorage: objectstorage.New(storageId+"TANGLE_TRANSACTION_STORAGE", transactionFactory),
}
}
func transactionFactory(key []byte) objectstorage.StorableObject {
result := transaction.FromStorage(key)
return result
}
package transaction
type Id [transactionIdLength]byte
const transactionIdLength = 64
package transaction
import (
"encoding"
)
type Payload interface {
encoding.BinaryMarshaler
encoding.BinaryUnmarshaler
GetType() int
}
package transaction
type PayloadId [payloadIdLength]byte
const payloadIdLength = 64
package transaction
import (
"sync"
"github.com/iotaledger/hive.go/objectstorage"
"golang.org/x/crypto/blake2b"
)
type Transaction struct {
// base functionality of StorableObject
objectstorage.StorableObjectFlags
// core properties (they are part of the transaction when being sent)
trunkTransactionId Id
branchTransactionId Id
payload Payload
// derived properties
id *Id
idMutex sync.RWMutex
payloadId *PayloadId
payloadIdMutex sync.RWMutex
bytes []byte
bytesMutex sync.RWMutex
}
func FromStorage(id []byte) (result *Transaction) {
var transactionId Id
copy(transactionId[:], id)
result = &Transaction{
id: &transactionId,
}
return
}
func (transaction *Transaction) GetId() (result Id) {
transaction.idMutex.RLock()
if transaction.id == nil {
transaction.idMutex.RLock()
transaction.idMutex.Lock()
if transaction.id == nil {
result = transaction.calculateTransactionId()
transaction.id = &result
} else {
result = *transaction.id
}
transaction.idMutex.Unlock()
} else {
result = *transaction.id
transaction.idMutex.RLock()
}
return
}
func (transaction *Transaction) GetPayloadId() (result PayloadId) {
transaction.payloadIdMutex.RLock()
if transaction.payloadId == nil {
transaction.payloadIdMutex.RLock()
transaction.payloadIdMutex.Lock()
if transaction.payloadId == nil {
result = transaction.calculatePayloadId()
transaction.payloadId = &result
} else {
result = *transaction.payloadId
}
transaction.payloadIdMutex.Unlock()
} else {
result = *transaction.payloadId
transaction.payloadIdMutex.RLock()
}
return
}
func (transaction *Transaction) GetBytes() (result []byte) {
transaction.bytesMutex.RLock()
if transaction.bytes == nil {
transaction.bytesMutex.RLock()
transaction.bytesMutex.Lock()
if transaction.bytes == nil {
var err error
if result, err = transaction.MarshalBinary(); err != nil {
// this should never happen
panic(err)
}
transaction.bytes = result
} else {
result = transaction.bytes
}
transaction.bytesMutex.Unlock()
} else {
result = transaction.bytes
transaction.bytesMutex.RLock()
}
return
}
func (transaction *Transaction) calculateTransactionId() Id {
payloadId := transaction.GetPayloadId()
hashBase := make([]byte, transactionIdLength+transactionIdLength+payloadIdLength)
offset := 0
copy(hashBase[offset:], transaction.trunkTransactionId[:])
offset += transactionIdLength
copy(hashBase[offset:], transaction.branchTransactionId[:])
offset += transactionIdLength
copy(hashBase[offset:], payloadId[:])
offset += payloadIdLength
return blake2b.Sum512(hashBase)
}
func (transaction *Transaction) calculatePayloadId() PayloadId {
bytes := transaction.GetBytes()
return blake2b.Sum512(bytes[2*transactionIdLength:])
}
func (transaction *Transaction) MarshalBinary() (result []byte, err error) {
result = make([]byte, 2*transactionIdLength)
if serializedPayload, serializationErr := transaction.payload.MarshalBinary(); serializationErr != nil {
err = serializationErr
return
} else {
result = append(result, serializedPayload...)
}
return
}
// TODO: FINISH
func (transaction *Transaction) UnmarshalBinary(date []byte) (err error) {
return
}
func (transaction *Transaction) GetStorageKey() []byte {
transactionId := transaction.GetId()
return transactionId[:]
}
// TODO: FINISH
func (transaction *Transaction) Update(other objectstorage.StorableObject) {}
package bitutils
import (
"unsafe"
)
type Offset int
func NewOffset() *Offset {
offset := Offset(0)
return &offset
}
func (offset *Offset) Inc(delta int) (newOffset int) {
newOffset = *(*int)(unsafe.Pointer(offset)) + delta
*offset = *(*Offset)(unsafe.Pointer(&newOffset))
return
}
package bitutils
import (
"fmt"
"testing"
)
func BenchmarkOffset_Inc(b *testing.B) {
var x Offset
for i := 0; i < b.N; i++ {
x.Inc(1)
}
}
func Benchmark_Inc(b *testing.B) {
x := 0
for i := 0; i < b.N; i++ {
x++
}
}
func TestOffset_Inc(t *testing.T) {
q := 3
j := &q
*j = 12
fmt.Println(q)
var x Offset
x.Inc(4)
fmt.Println(x)
}
...@@ -222,8 +222,8 @@ func TestAggregateAggregatedRealities(t *testing.T) { ...@@ -222,8 +222,8 @@ func TestAggregateAggregatedRealities(t *testing.T) {
outputs1 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[1])[0]) outputs1 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[1])[0])
multiSpend(ledgerState, 1, transferOutputs[1]) multiSpend(ledgerState, 1, transferOutputs[1])
multiSpend(ledgerState, 1, transferOutputs[2])
outputs2 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[2])[0]) outputs2 := multiSpend(ledgerState, 2, multiSpend(ledgerState, 1, transferOutputs[2])[0])
multiSpend(ledgerState, 1, transferOutputs[2])
aggregatedOutputs0 := multiSpend(ledgerState, 2, outputs0[0], outputs1[0]) aggregatedOutputs0 := multiSpend(ledgerState, 2, outputs0[0], outputs1[0])
aggregatedOutputs1 := multiSpend(ledgerState, 2, outputs1[1], outputs2[1]) aggregatedOutputs1 := multiSpend(ledgerState, 2, outputs1[1], outputs2[1])
......
packages/ledgerstate/outputs1.png

102 KiB | W: | H:

packages/ledgerstate/outputs1.png

105 KiB | W: | H:

packages/ledgerstate/outputs1.png
packages/ledgerstate/outputs1.png
packages/ledgerstate/outputs1.png
packages/ledgerstate/outputs1.png
  • 2-up
  • Swipe
  • Onion skin
packages/ledgerstate/outputs2.png

118 KiB | W: | H:

packages/ledgerstate/outputs2.png

120 KiB | W: | H:

packages/ledgerstate/outputs2.png
packages/ledgerstate/outputs2.png
packages/ledgerstate/outputs2.png
packages/ledgerstate/outputs2.png
  • 2-up
  • Swipe
  • Onion skin
packages/ledgerstate/realities1.png

103 KiB | W: | H:

packages/ledgerstate/realities1.png

103 KiB | W: | H:

packages/ledgerstate/realities1.png
packages/ledgerstate/realities1.png
packages/ledgerstate/realities1.png
packages/ledgerstate/realities1.png
  • 2-up
  • Swipe
  • Onion skin
packages/ledgerstate/realities2.png

127 KiB | W: | H:

packages/ledgerstate/realities2.png

126 KiB | W: | H:

packages/ledgerstate/realities2.png
packages/ledgerstate/realities2.png
packages/ledgerstate/realities2.png
packages/ledgerstate/realities2.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -3,6 +3,8 @@ package ledgerstate ...@@ -3,6 +3,8 @@ package ledgerstate
import ( import (
"encoding/binary" "encoding/binary"
"github.com/iotaledger/hive.go/bitmask"
"github.com/iotaledger/hive.go/objectstorage" "github.com/iotaledger/hive.go/objectstorage"
) )
...@@ -26,11 +28,21 @@ func (reality *Reality) MarshalBinary() ([]byte, error) { ...@@ -26,11 +28,21 @@ func (reality *Reality) MarshalBinary() ([]byte, error) {
parentRealityCount := len(reality.parentRealityIds) parentRealityCount := len(reality.parentRealityIds)
subRealityCount := len(reality.subRealityIds) subRealityCount := len(reality.subRealityIds)
marshaledReality := make([]byte, 4+4+4+1+parentRealityCount*realityIdLength+subRealityCount*realityIdLength) marshaledReality := make([]byte, 1+4+4+4+parentRealityCount*realityIdLength+subRealityCount*realityIdLength)
offset := 0 offset := 0
binary.LittleEndian.PutUint32(marshaledReality, uint32(reality.GetTransferOutputCount())) var flags bitmask.BitMask
if reality.IsPreferred() {
flags = flags.SetFlag(0)
}
if reality.IsLiked() {
flags = flags.SetFlag(1)
}
marshaledReality[offset] = byte(flags)
offset += 1
binary.LittleEndian.PutUint32(marshaledReality[offset:], reality.GetTransferOutputCount())
offset += 4 offset += 4
binary.LittleEndian.PutUint32(marshaledReality[offset:], uint32(parentRealityCount)) binary.LittleEndian.PutUint32(marshaledReality[offset:], uint32(parentRealityCount))
...@@ -49,59 +61,87 @@ func (reality *Reality) MarshalBinary() ([]byte, error) { ...@@ -49,59 +61,87 @@ func (reality *Reality) MarshalBinary() ([]byte, error) {
offset += realityIdLength offset += realityIdLength
} }
if reality.liked {
marshaledReality[offset] = 1
} else {
marshaledReality[offset] = 0
}
//offset += 1
reality.parentRealityIdsMutex.RUnlock() reality.parentRealityIdsMutex.RUnlock()
return marshaledReality, nil return marshaledReality, nil
} }
func (reality *Reality) UnmarshalBinary(serializedObject []byte) error { func (reality *Reality) UnmarshalBinary(serializedObject []byte) (err error) {
if err := reality.id.UnmarshalBinary(reality.storageKey[:realityIdLength]); err != nil { if err = reality.id.UnmarshalBinary(reality.storageKey[:realityIdLength]); err != nil {
return err return
} }
reality.parentRealityIds = NewRealityIdSet()
reality.subRealityIds = NewRealityIdSet()
offset := 0 offset := 0
reality.transferOutputCount = binary.LittleEndian.Uint32(serializedObject) reality.unmarshalBinaryFlags(serializedObject, &offset)
offset += 4
parentRealityCount := int(binary.LittleEndian.Uint32(serializedObject[offset:])) reality.unmarshalBinaryTransferOutputCount(serializedObject, &offset)
offset += 4
if err = reality.unmarshalBinaryParentRealities(serializedObject, &offset); err != nil {
return
}
if err = reality.unmarshalBinarySubRealities(serializedObject, &offset); err != nil {
return
}
return nil
}
func (reality *Reality) unmarshalBinaryFlags(serializedObject []byte, offset *int) {
var flags = bitmask.BitMask(serializedObject[*offset])
if flags.HasFlag(0) {
reality.preferred = true
}
if flags.HasFlag(1) {
reality.liked = true
}
*offset += 1
}
func (reality *Reality) unmarshalBinaryTransferOutputCount(serializedObject []byte, offset *int) {
reality.transferOutputCount = binary.LittleEndian.Uint32(serializedObject[*offset:])
*offset = *offset + 4
}
func (reality *Reality) unmarshalBinaryParentRealities(serializedObject []byte, offset *int) (err error) {
reality.parentRealityIds = NewRealityIdSet()
parentRealityCount := int(binary.LittleEndian.Uint32(serializedObject[*offset:]))
*offset += 4
for i := 0; i < parentRealityCount; i++ { for i := 0; i < parentRealityCount; i++ {
var restoredRealityId RealityId var restoredRealityId RealityId
if err := restoredRealityId.UnmarshalBinary(serializedObject[offset:]); err != nil { if err = restoredRealityId.UnmarshalBinary(serializedObject[*offset:]); err != nil {
return err return
} }
offset += realityIdLength *offset += realityIdLength
reality.parentRealityIds[restoredRealityId] = void reality.parentRealityIds[restoredRealityId] = void
} }
subRealityCount := int(binary.LittleEndian.Uint32(serializedObject[offset:])) return
offset += 4 }
func (reality *Reality) unmarshalBinarySubRealities(serializedObject []byte, offset *int) (err error) {
reality.subRealityIds = NewRealityIdSet()
subRealityCount := int(binary.LittleEndian.Uint32(serializedObject[*offset:]))
*offset += 4
for i := 0; i < subRealityCount; i++ { for i := 0; i < subRealityCount; i++ {
var restoredRealityId RealityId var restoredRealityId RealityId
if err := restoredRealityId.UnmarshalBinary(serializedObject[offset:]); err != nil { if err = restoredRealityId.UnmarshalBinary(serializedObject[*offset:]); err != nil {
return err return
} }
offset += realityIdLength *offset += realityIdLength
reality.subRealityIds[restoredRealityId] = void reality.subRealityIds[restoredRealityId] = void
} }
reality.liked = serializedObject[offset] == 1 return
//offset += 1
return nil
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment