forked from stellar/go
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
xdrill for ledgerCloseMeta (stellar#5568)
- Loading branch information
Showing
5 changed files
with
384 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
package ledger | ||
|
||
import ( | ||
"encoding/base64" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/stellar/go/xdr" | ||
) | ||
|
||
func Sequence(l xdr.LedgerCloseMeta) uint32 { | ||
return uint32(l.LedgerHeaderHistoryEntry().Header.LedgerSeq) | ||
} | ||
|
||
func Hash(l xdr.LedgerCloseMeta) string { | ||
return l.LedgerHeaderHistoryEntry().Hash.HexString() | ||
} | ||
|
||
func PreviousHash(l xdr.LedgerCloseMeta) string { | ||
return l.PreviousLedgerHash().HexString() | ||
} | ||
|
||
func CloseTime(l xdr.LedgerCloseMeta) int64 { | ||
return l.LedgerCloseTime() | ||
} | ||
|
||
func ClosedAt(l xdr.LedgerCloseMeta) time.Time { | ||
return time.Unix(l.LedgerCloseTime(), 0).UTC() | ||
} | ||
|
||
func TotalCoins(l xdr.LedgerCloseMeta) int64 { | ||
return int64(l.LedgerHeaderHistoryEntry().Header.TotalCoins) | ||
} | ||
|
||
func FeePool(l xdr.LedgerCloseMeta) int64 { | ||
return int64(l.LedgerHeaderHistoryEntry().Header.FeePool) | ||
} | ||
|
||
func BaseFee(l xdr.LedgerCloseMeta) uint32 { | ||
return uint32(l.LedgerHeaderHistoryEntry().Header.BaseFee) | ||
} | ||
|
||
func BaseReserve(l xdr.LedgerCloseMeta) uint32 { | ||
return uint32(l.LedgerHeaderHistoryEntry().Header.BaseReserve) | ||
} | ||
|
||
func MaxTxSetSize(l xdr.LedgerCloseMeta) uint32 { | ||
return uint32(l.LedgerHeaderHistoryEntry().Header.MaxTxSetSize) | ||
} | ||
|
||
func LedgerVersion(l xdr.LedgerCloseMeta) uint32 { | ||
return uint32(l.LedgerHeaderHistoryEntry().Header.LedgerVersion) | ||
} | ||
|
||
func SorobanFeeWrite1Kb(l xdr.LedgerCloseMeta) (int64, bool) { | ||
lcmV1, ok := l.GetV1() | ||
if !ok { | ||
return 0, false | ||
} | ||
|
||
extV1, ok := lcmV1.Ext.GetV1() | ||
if !ok { | ||
return 0, false | ||
} | ||
|
||
return int64(extV1.SorobanFeeWrite1Kb), true | ||
} | ||
|
||
func TotalByteSizeOfBucketList(l xdr.LedgerCloseMeta) (uint64, bool) { | ||
lcmV1, ok := l.GetV1() | ||
if !ok { | ||
return 0, false | ||
} | ||
|
||
return uint64(lcmV1.TotalByteSizeOfBucketList), true | ||
} | ||
|
||
func NodeID(l xdr.LedgerCloseMeta) (string, error) { | ||
LedgerCloseValueSignature, ok := l.LedgerHeaderHistoryEntry().Header.ScpValue.Ext.GetLcValueSignature() | ||
if !ok { | ||
return "", fmt.Errorf("could not get LedgerCloseValueSignature") | ||
|
||
} | ||
return LedgerCloseValueSignature.NodeId.GetAddress() | ||
} | ||
|
||
func Signature(l xdr.LedgerCloseMeta) (string, bool) { | ||
LedgerCloseValueSignature, ok := l.LedgerHeaderHistoryEntry().Header.ScpValue.Ext.GetLcValueSignature() | ||
if !ok { | ||
return "", false | ||
} | ||
|
||
return base64.StdEncoding.EncodeToString(LedgerCloseValueSignature.Signature), true | ||
} | ||
|
||
// TransactionCounts calculates and returns the number of successful and total transactions | ||
func TransactionCounts(l xdr.LedgerCloseMeta) (successTxCount, totalTxCount uint32) { | ||
transactions := l.TransactionEnvelopes() | ||
results, err := l.TxProcessing() | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
txCount := len(transactions) | ||
if txCount != len(results) { | ||
panic("transaction count and number of TransactionResultMeta not equal") | ||
} | ||
|
||
for i := 0; i < txCount; i++ { | ||
if results[i].Result.Successful() { | ||
successTxCount++ | ||
} | ||
} | ||
|
||
return successTxCount, uint32(txCount) | ||
} | ||
|
||
// OperationCounts calculates and returns the number of successful operations and the total operations within | ||
// a LedgerCloseMeta | ||
func OperationCounts(l xdr.LedgerCloseMeta) (successfulOperationCount, totalOperationCount uint32) { | ||
transactions := l.TransactionEnvelopes() | ||
results, err := l.TxProcessing() | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
for i, result := range results { | ||
operations := transactions[i].OperationsCount() | ||
totalOperationCount += operations | ||
|
||
// for successful transactions, the operation count is based on the operations results slice | ||
if result.Result.Successful() { | ||
operationResults, ok := result.Result.OperationResults() | ||
if !ok { | ||
panic("could not get OperationResults") | ||
} | ||
|
||
successfulOperationCount += uint32(len(operationResults)) | ||
} | ||
} | ||
|
||
return successfulOperationCount, totalOperationCount | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
package ledger | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/stellar/go/keypair" | ||
"github.com/stellar/go/txnbuild" | ||
"github.com/stellar/go/xdr" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestLedger(t *testing.T) { | ||
ledger := ledgerTestInput() | ||
|
||
assert.Equal(t, uint32(30578981), Sequence(ledger)) | ||
assert.Equal(t, "26932dc4d84b5fabe9ae744cb43ce4c6daccf98c86a991b2a14945b1adac4d59", Hash(ledger)) | ||
assert.Equal(t, "f63c15d0eaf48afbd751a4c4dfade54a3448053c47c5a71d622668ae0cc2a208", PreviousHash(ledger)) | ||
assert.Equal(t, int64(1594584547), CloseTime(ledger)) | ||
assert.Equal(t, time.Time(time.Date(2020, time.July, 12, 20, 9, 7, 0, time.UTC)), ClosedAt(ledger)) | ||
assert.Equal(t, int64(1054439020873472865), TotalCoins(ledger)) | ||
assert.Equal(t, int64(18153766209161), FeePool(ledger)) | ||
assert.Equal(t, uint32(100), BaseFee(ledger)) | ||
assert.Equal(t, uint32(5000000), BaseReserve(ledger)) | ||
assert.Equal(t, uint32(1000), MaxTxSetSize(ledger)) | ||
assert.Equal(t, uint32(13), LedgerVersion(ledger)) | ||
|
||
var ok bool | ||
var freeWrite int64 | ||
freeWrite, ok = SorobanFeeWrite1Kb(ledger) | ||
assert.Equal(t, true, ok) | ||
assert.Equal(t, int64(12), freeWrite) | ||
|
||
var bucketSize uint64 | ||
bucketSize, ok = TotalByteSizeOfBucketList(ledger) | ||
assert.Equal(t, true, ok) | ||
assert.Equal(t, uint64(56), bucketSize) | ||
|
||
var nodeID string | ||
var err error | ||
nodeID, err = NodeID(ledger) | ||
assert.Equal(t, nil, err) | ||
assert.Equal(t, "GARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA76O", nodeID) | ||
|
||
var signature string | ||
signature, ok = Signature(ledger) | ||
assert.Equal(t, true, ok) | ||
assert.Equal(t, "9g==", signature) | ||
|
||
var success uint32 | ||
var total uint32 | ||
success, total = TransactionCounts(ledger) | ||
assert.Equal(t, uint32(1), success) | ||
assert.Equal(t, uint32(2), total) | ||
|
||
success, total = OperationCounts(ledger) | ||
assert.Equal(t, uint32(1), success) | ||
assert.Equal(t, uint32(13), total) | ||
} | ||
|
||
func ledgerTestInput() (lcm xdr.LedgerCloseMeta) { | ||
lcm = xdr.LedgerCloseMeta{ | ||
V: 1, | ||
V1: &xdr.LedgerCloseMetaV1{ | ||
Ext: xdr.LedgerCloseMetaExt{ | ||
V: 1, | ||
V1: &xdr.LedgerCloseMetaExtV1{ | ||
SorobanFeeWrite1Kb: xdr.Int64(12), | ||
}, | ||
}, | ||
LedgerHeader: xdr.LedgerHeaderHistoryEntry{ | ||
Hash: xdr.Hash{0x26, 0x93, 0x2d, 0xc4, 0xd8, 0x4b, 0x5f, 0xab, 0xe9, 0xae, 0x74, 0x4c, 0xb4, 0x3c, 0xe4, 0xc6, 0xda, 0xcc, 0xf9, 0x8c, 0x86, 0xa9, 0x91, 0xb2, 0xa1, 0x49, 0x45, 0xb1, 0xad, 0xac, 0x4d, 0x59}, | ||
Header: xdr.LedgerHeader{ | ||
LedgerSeq: 30578981, | ||
TotalCoins: 1054439020873472865, | ||
FeePool: 18153766209161, | ||
BaseFee: 100, | ||
BaseReserve: 5000000, | ||
MaxTxSetSize: 1000, | ||
LedgerVersion: 13, | ||
PreviousLedgerHash: xdr.Hash{0xf6, 0x3c, 0x15, 0xd0, 0xea, 0xf4, 0x8a, 0xfb, 0xd7, 0x51, 0xa4, 0xc4, 0xdf, 0xad, 0xe5, 0x4a, 0x34, 0x48, 0x5, 0x3c, 0x47, 0xc5, 0xa7, 0x1d, 0x62, 0x26, 0x68, 0xae, 0xc, 0xc2, 0xa2, 0x8}, | ||
ScpValue: xdr.StellarValue{ | ||
Ext: xdr.StellarValueExt{ | ||
V: 1, | ||
LcValueSignature: &xdr.LedgerCloseValueSignature{ | ||
NodeId: xdr.NodeId{ | ||
Type: 0, | ||
Ed25519: &xdr.Uint256{34}, | ||
}, | ||
Signature: []byte{0xf6}, | ||
}, | ||
}, | ||
CloseTime: 1594584547, | ||
}, | ||
}, | ||
}, | ||
TotalByteSizeOfBucketList: xdr.Uint64(56), | ||
TxSet: xdr.GeneralizedTransactionSet{ | ||
V: 0, | ||
V1TxSet: &xdr.TransactionSetV1{ | ||
Phases: []xdr.TransactionPhase{ | ||
{ | ||
V: 0, | ||
V0Components: &[]xdr.TxSetComponent{ | ||
{ | ||
Type: 0, | ||
TxsMaybeDiscountedFee: &xdr.TxSetComponentTxsMaybeDiscountedFee{ | ||
Txs: []xdr.TransactionEnvelope{ | ||
createSampleTx(3), | ||
createSampleTx(10), | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
TxProcessing: []xdr.TransactionResultMeta{ | ||
{ | ||
Result: xdr.TransactionResultPair{ | ||
Result: xdr.TransactionResult{ | ||
Result: xdr.TransactionResultResult{ | ||
Code: xdr.TransactionResultCodeTxSuccess, | ||
Results: &[]xdr.OperationResult{ | ||
{ | ||
Code: xdr.OperationResultCodeOpInner, | ||
Tr: &xdr.OperationResultTr{ | ||
Type: xdr.OperationTypeCreateAccount, | ||
CreateAccountResult: &xdr.CreateAccountResult{ | ||
Code: 0, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
Result: xdr.TransactionResultPair{ | ||
Result: xdr.TransactionResult{ | ||
Result: xdr.TransactionResultResult{ | ||
Code: xdr.TransactionResultCodeTxFailed, | ||
Results: &[]xdr.OperationResult{ | ||
{ | ||
Code: xdr.OperationResultCodeOpInner, | ||
Tr: &xdr.OperationResultTr{ | ||
Type: xdr.OperationTypeCreateAccount, | ||
CreateAccountResult: &xdr.CreateAccountResult{ | ||
Code: 0, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
return lcm | ||
} | ||
|
||
func createSampleTx(operationCount int) xdr.TransactionEnvelope { | ||
kp, err := keypair.Random() | ||
panicOnError(err) | ||
|
||
operations := []txnbuild.Operation{} | ||
operationType := &txnbuild.BumpSequence{ | ||
BumpTo: 0, | ||
} | ||
for i := 0; i < operationCount; i++ { | ||
operations = append(operations, operationType) | ||
} | ||
|
||
sourceAccount := txnbuild.NewSimpleAccount(kp.Address(), int64(0)) | ||
tx, err := txnbuild.NewTransaction( | ||
txnbuild.TransactionParams{ | ||
SourceAccount: &sourceAccount, | ||
Operations: operations, | ||
BaseFee: txnbuild.MinBaseFee, | ||
Preconditions: txnbuild.Preconditions{TimeBounds: txnbuild.NewInfiniteTimeout()}, | ||
}, | ||
) | ||
panicOnError(err) | ||
|
||
env := tx.ToXDR() | ||
return env | ||
} | ||
|
||
// PanicOnError is a function that panics if the provided error is not nil | ||
func panicOnError(err error) { | ||
if err != nil { | ||
panic(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package xdr | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/stellar/go/strkey" | ||
) | ||
|
||
func (n NodeId) GetAddress() (string, error) { | ||
switch n.Type { | ||
case PublicKeyTypePublicKeyTypeEd25519: | ||
ed, ok := n.GetEd25519() | ||
if !ok { | ||
return "", fmt.Errorf("could not get NodeID.Ed25519") | ||
} | ||
raw := make([]byte, 32) | ||
copy(raw, ed[:]) | ||
encodedAddress, err := strkey.Encode(strkey.VersionByteAccountID, raw) | ||
if err != nil { | ||
return "", err | ||
} | ||
return encodedAddress, nil | ||
default: | ||
return "", fmt.Errorf("unknown NodeId.PublicKeyType") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters