value_transaction.go 7.19 KiB
package value_transaction
import (
"sync"
"github.com/iotaledger/goshimmer/packages/model/meta_transaction"
"github.com/iotaledger/goshimmer/packages/ternary"
)
type ValueTransaction struct {
*meta_transaction.MetaTransaction
address *ternary.Trinary
addressMutex sync.RWMutex
value *int64
valueMutex sync.RWMutex
timestamp *uint
timestampMutex sync.RWMutex
nonce *ternary.Trinary
nonceMutex sync.RWMutex
signatureMessageFragment *ternary.Trinary
signatureMessageFragmentMutex sync.RWMutex
trits ternary.Trits
}
func New() (result *ValueTransaction) {
result = &ValueTransaction{
MetaTransaction: meta_transaction.New(),
}
result.trits = result.MetaTransaction.GetData()
return
}
func FromMetaTransaction(metaTransaction *meta_transaction.MetaTransaction) *ValueTransaction {
return &ValueTransaction{
MetaTransaction: metaTransaction,
trits: metaTransaction.GetData(),
}
}
func FromBytes(bytes []byte) (result *ValueTransaction) {
result = &ValueTransaction{
MetaTransaction: meta_transaction.FromTrits(ternary.BytesToTrits(bytes)[:meta_transaction.MARSHALLED_TOTAL_SIZE]),
}
result.trits = result.MetaTransaction.GetData()
return
}
// getter for the address (supports concurrency)
func (this *ValueTransaction) GetAddress() (result ternary.Trinary) {
this.addressMutex.RLock()
if this.address == nil {
this.addressMutex.RUnlock()
this.addressMutex.Lock()
defer this.addressMutex.Unlock()
if this.address == nil {
address := this.trits[ADDRESS_OFFSET:ADDRESS_END].ToTrinary()
this.address = &address
}
} else {
defer this.addressMutex.RUnlock()
}
result = *this.address
return
}
// setter for the address (supports concurrency)
func (this *ValueTransaction) SetAddress(address ternary.Trinary) bool {
this.addressMutex.RLock()
if this.address == nil || *this.address != address {
this.addressMutex.RUnlock()
this.addressMutex.Lock()
defer this.addressMutex.Unlock()
if this.address == nil || *this.address != address {
this.address = &address
this.BlockHasher()
copy(this.trits[ADDRESS_OFFSET:ADDRESS_END], address.ToTrits()[:ADDRESS_SIZE])
this.UnblockHasher()
this.SetModified(true)
this.ReHash()
return true
}
} else {
this.addressMutex.RUnlock()
}
return false
}
// getter for the value (supports concurrency)
func (this *ValueTransaction) GetValue() (result int64) {
this.valueMutex.RLock()
if this.value == nil {
this.valueMutex.RUnlock()
this.valueMutex.Lock()
defer this.valueMutex.Unlock()
if this.value == nil {
value := this.trits[VALUE_OFFSET:VALUE_END].ToInt64()
this.value = &value
}
} else {
defer this.valueMutex.RUnlock()
}
result = *this.value
return
}
// setter for the value (supports concurrency)
func (this *ValueTransaction) SetValue(value int64) bool {
this.valueMutex.RLock()
if this.value == nil || *this.value != value {
this.valueMutex.RUnlock()
this.valueMutex.Lock()
defer this.valueMutex.Unlock()
if this.value == nil || *this.value != value {
this.value = &value
this.BlockHasher()
copy(this.trits[VALUE_OFFSET:VALUE_END], ternary.Int64ToTrits(value)[:VALUE_SIZE])
this.UnblockHasher()
this.SetModified(true)
this.ReHash()
return true
}
} else {
this.valueMutex.RUnlock()
}
return false
}
// getter for the timestamp (supports concurrency)
func (this *ValueTransaction) GetTimestamp() (result uint) {
this.timestampMutex.RLock()
if this.timestamp == nil {
this.timestampMutex.RUnlock()
this.timestampMutex.Lock()
defer this.timestampMutex.Unlock()
if this.timestamp == nil {
timestamp := this.trits[TIMESTAMP_OFFSET:TIMESTAMP_END].ToUint()
this.timestamp = ×tamp
}
} else {
defer this.timestampMutex.RUnlock()
}
result = *this.timestamp
return
}
// setter for the timestamp (supports concurrency)
func (this *ValueTransaction) SetTimestamp(timestamp uint) bool {
this.timestampMutex.RLock()
if this.timestamp == nil || *this.timestamp != timestamp {
this.timestampMutex.RUnlock()
this.timestampMutex.Lock()
defer this.timestampMutex.Unlock()
if this.timestamp == nil || *this.timestamp != timestamp {
this.timestamp = ×tamp
this.BlockHasher()
copy(this.trits[TIMESTAMP_OFFSET:TIMESTAMP_END], ternary.UintToTrits(timestamp)[:TIMESTAMP_SIZE])
this.UnblockHasher()
this.SetModified(true)
this.ReHash()
return true
}
} else {
this.timestampMutex.RUnlock()
}
return false
}
// getter for the nonce (supports concurrency)
func (this *ValueTransaction) GetNonce() (result ternary.Trinary) {
this.nonceMutex.RLock()
if this.nonce == nil {
this.nonceMutex.RUnlock()
this.nonceMutex.Lock()
defer this.nonceMutex.Unlock()
if this.nonce == nil {
nonce := this.trits[NONCE_OFFSET:NONCE_END].ToTrinary()
this.nonce = &nonce
}
} else {
defer this.nonceMutex.RUnlock()
}
result = *this.nonce
return
}
// setter for the nonce (supports concurrency)
func (this *ValueTransaction) SetNonce(nonce ternary.Trinary) bool {
this.nonceMutex.RLock()
if this.nonce == nil || *this.nonce != nonce {
this.nonceMutex.RUnlock()
this.nonceMutex.Lock()
defer this.nonceMutex.Unlock()
if this.nonce == nil || *this.nonce != nonce {
this.nonce = &nonce
this.BlockHasher()
copy(this.trits[NONCE_OFFSET:NONCE_END], nonce.ToTrits()[:NONCE_SIZE])
this.UnblockHasher()
this.SetModified(true)
this.ReHash()
return true
}
} else {
this.nonceMutex.RUnlock()
}
return false
}
// getter for the signatureMessageFragmetn (supports concurrency)
func (this *ValueTransaction) GetSignatureMessageFragment() (result ternary.Trinary) {
this.signatureMessageFragmentMutex.RLock()
if this.signatureMessageFragment == nil {
this.signatureMessageFragmentMutex.RUnlock()
this.signatureMessageFragmentMutex.Lock()
defer this.signatureMessageFragmentMutex.Unlock()
if this.signatureMessageFragment == nil {
signatureMessageFragment := this.trits[SIGNATURE_MESSAGE_FRAGMENT_OFFSET:SIGNATURE_MESSAGE_FRAGMENT_END].ToTrinary()
this.signatureMessageFragment = &signatureMessageFragment
}
} else {
defer this.signatureMessageFragmentMutex.RUnlock()
}
result = *this.signatureMessageFragment
return
}
// setter for the nonce (supports concurrency)
func (this *ValueTransaction) SetSignatureMessageFragment(signatureMessageFragment ternary.Trinary) bool {
this.signatureMessageFragmentMutex.RLock()
if this.signatureMessageFragment == nil || *this.signatureMessageFragment != signatureMessageFragment {
this.signatureMessageFragmentMutex.RUnlock()
this.signatureMessageFragmentMutex.Lock()
defer this.signatureMessageFragmentMutex.Unlock()
if this.signatureMessageFragment == nil || *this.signatureMessageFragment != signatureMessageFragment {
this.signatureMessageFragment = &signatureMessageFragment
this.BlockHasher()
copy(this.trits[SIGNATURE_MESSAGE_FRAGMENT_OFFSET:SIGNATURE_MESSAGE_FRAGMENT_END], signatureMessageFragment.ToTrits()[:SIGNATURE_MESSAGE_FRAGMENT_SIZE])
this.UnblockHasher()
this.SetModified(true)
this.ReHash()
return true
}
} else {
this.signatureMessageFragmentMutex.RUnlock()
}
return false
}