@@ -27,6 +27,7 @@ func (d *Pegnetd) GetCurrentSync() uint32 {
2727func (d * Pegnetd ) DBlockSync (ctx context.Context ) {
2828 retryPeriod := d .Config .GetDuration (config .DBlockSyncRetryPeriod )
2929 isFirstSync := true
30+
3031OuterSyncLoop:
3132 for {
3233 if isDone (ctx ) {
@@ -85,6 +86,16 @@ OuterSyncLoop:
8586 hLog .WithError (err ).Errorf ("failed to start transaction" )
8687 continue
8788 }
89+
90+ ////////////////////////
91+ // Zeroing funds at Global Burn Address
92+
93+ // One time operation, Inserts negative balance for the burn address that used during the attack
94+ // We need to do this before main logic because sqlite db will be locked
95+ if d .Sync .Synced + 1 == V20HeightActivation {
96+ d .NullifyBurnAddress (ctx , tx , d .Sync .Synced + 1 )
97+ }
98+
8899 // We are not synced, so we need to iterate through the dblocks and sync them
89100 // one by one. We can only sync our current synced height +1
90101 // TODO: This skips the genesis block. I'm sure that is fine
@@ -157,6 +168,57 @@ OuterSyncLoop:
157168
158169}
159170
171+ func (d * Pegnetd ) NullifyBurnAddress (ctx context.Context , tx * sql.Tx , height uint32 ) error {
172+ fLog := log .WithFields (log.Fields {"height" : height })
173+
174+ dblock := new (factom.DBlock )
175+ dblock .Height = height
176+ if err := dblock .Get (nil , d .FactomClient ); err != nil {
177+ return err
178+ }
179+ heightTimestamp := dblock .Timestamp
180+ // We need to mock a TXID to record zeroing
181+ txid := fmt .Sprintf ("%064d" , height )
182+
183+ // 1. check current balance
184+ // 2. substract amounts for every ticker
185+
186+ // Get all balances for the address
187+ balances , err := d .Pegnet .SelectBalances (& FAGlobalBurnAddress )
188+
189+ if err != nil {
190+ fLog .WithFields (log.Fields {
191+ "err" : err ,
192+ }).Info ("zeroing burn | balances retrieval failed" )
193+ }
194+
195+ for ticker := fat2 .PTickerInvalid + 1 ; ticker < fat2 .PTickerMax ; ticker ++ {
196+ // Substract from every issuance
197+ value , _ := balances [ticker ]
198+ _ , _ , err := d .Pegnet .SubFromBalance (tx , & FAGlobalBurnAddress , ticker , value ) // lastInd, txErr, err
199+ if err != nil {
200+ fLog .WithFields (log.Fields {
201+ "ticker" : ticker ,
202+ "balance" : value ,
203+ }).Info ("zeroing burn | substract from balance failed" )
204+ }
205+
206+ // Mock entry hash value
207+ addTxid := fmt .Sprintf ("%d-%s" , ticker , txid )
208+
209+ err = d .Pegnet .InsertZeroingCoinbase (tx , txid , addTxid , height , heightTimestamp , value , ticker .String (), FAGlobalBurnAddress )
210+ if err != nil {
211+ fLog .WithFields (log.Fields {
212+ "error" : err ,
213+ }).Info ("zeroing burn | coinbase tx failed" )
214+ return err
215+ }
216+
217+ }
218+
219+ return nil
220+ }
221+
160222// If SyncBlock returns no error, than that height was synced and saved. If any part of the sync fails,
161223// the whole sync should be rolled back and not applied. An error should then be returned.
162224// The context should be respected if it is cancelled
@@ -811,7 +873,8 @@ func (d *Pegnetd) recordBatch(sqlTx *sql.Tx, txBatch *fat2.TransactionBatch, rat
811873 }
812874
813875 // Outputs
814- if tx .IsConversion () { // Conv Output
876+ if tx .IsConversion () {
877+ // Conversions Output
815878 outputAmount , err := conversions .Convert (int64 (tx .Input .Amount ), rates [tx .Input .Type ], rates [tx .Conversion ])
816879 if err != nil {
817880 return err
@@ -820,19 +883,26 @@ func (d *Pegnetd) recordBatch(sqlTx *sql.Tx, txBatch *fat2.TransactionBatch, rat
820883 if err = d .Pegnet .SetTransactionHistoryConvertedAmount (sqlTx , txBatch , txIndex , outputAmount ); err != nil {
821884 return err
822885 }
886+
823887 _ , err = d .Pegnet .AddToBalance (sqlTx , & tx .Input .Address , tx .Conversion , uint64 (outputAmount ))
824888 if err != nil {
825889 return err
826890 }
827- } else { // Transfer Outputs
891+
892+ } else {
893+ // Transfer Outputs
894+
828895 for _ , transfer := range tx .Transfers {
829- _ , err = d .Pegnet .AddToBalance (sqlTx , & transfer .Address , tx .Input .Type , transfer .Amount )
830- if err != nil {
831- return err
832- }
833- _ , err = d .Pegnet .InsertTransactionRelation (sqlTx , transfer .Address , txBatch .Entry .Hash , uint64 (txIndex ), true , false )
834- if err != nil {
835- return err
896+ // if transfer to Burn address do nothing, otherwise add balances
897+ if transfer .Address != FAGlobalBurnAddress {
898+ _ , err = d .Pegnet .AddToBalance (sqlTx , & transfer .Address , tx .Input .Type , transfer .Amount )
899+ if err != nil {
900+ return err
901+ }
902+ _ , err = d .Pegnet .InsertTransactionRelation (sqlTx , transfer .Address , txBatch .Entry .Hash , uint64 (txIndex ), true , false )
903+ if err != nil {
904+ return err
905+ }
836906 }
837907 }
838908 }
0 commit comments